title: Calling API service and setting recyclerView adapter from in Firebase onDataChange?
body: <p>I'm new to java android and completely stuck on this problem. </p>
  
  <p><strong>The following is working:</strong></p>
  
  <ol>
  <li><p>User logs in, App generates 30 random photos from UnSpash.com through their API. Photos are placed on screen by RecyclerView. My <code>getFoodPictures()</code></p></li>
  <li><p>Logged in users of app can edit a picture with a description. This
      is saved to Firebase (User, Picture ID, &amp; description).</p></li>
  <li><p>App retrieves a user's Described photos from Firebase when they log in and
  stores in array. my <code>getUserFood()</code> method using Firebase <code>addListenerForSingleValueEvent</code></p></li>
  </ol>
  
  <p><strong>Not Working:</strong></p>
  
  <p>When user logs in, I want RecyclerView as it binds each photo to view, to compare each API generated photo with User's array of Described Photos(that I got from Firebase).  And if API photo is in the User's array of Described photos, then bind the view with the User's Described photo instead of API one.  </p>
  
  <p><strong>The problem, as I understand it, is async</strong></p>
  
  <p>From research on here, Firebase `addListenerForSingleValueEvent' is async. So I end up getting the Users Photo descriptions from Firebase <strong>AFTER</strong> the API call and RecyclerView do their job. </p>
  
  <p>Many posts here recommended thinking about working with Firebase onDataChange with a mindset of:</p>
  
  <p>"When data is returned, then do something with data".  </p>
  
  <p><strong>Moved API+RecyclerView method into FireBase call for user data</strong></p>
  
  <p>So I moved my API+RecyclerView method <code>getFoodPictures()</code> into the Firebase method to get User data. <code>getFoodPictures()</code> is called from inside onDataChange. </p>
  
  <p><strong>Images appear for a moment and then disappear</strong></p>
  
  <p>Doing this has resolved my async issue. User data from Firebase is returned before RecyclerView starts binding views. </p>
  
  <p>But, as RecyclerView goes into action and binds the views, the images appear for a flickr and then are gone. App doesn't crash, I can still log out and log in from the menu. There just isn't any list to scroll through. </p>
  
  <p><strong>What would be helpful to me</strong></p>
  
  <ol>
  <li><p>Before I moved my API call into the Firebase method, I tried to
  figure out how to save the User data returned from Firebase
  <strong>BEFORE</strong> API call and recycler view started.   </p>
  
  <p>I didn't get it.  Some posts mentioned Interfaces and I'm too new to
  understand the examples they provided. </p>
  
  <p>If you have a clear example of how to get and set Firebase data <strong>BEFORE</strong> my
  API+recycler view do their job, please share.</p></li>
  <li><p>Assuming I am on a right track by placing <code>getFoodPictures()</code>
  inside the Firebase onDataChange,  how do I get the images
  and recyclerView to not disappear?</p></li>
  </ol>
  
  <p>My UnSpash Service seting up the API call</p>
  
  <pre><code>public class UnSplashService {
      public static void getPictures(Callback callback){
          HttpUrl.Builder urlBuilder = HttpUrl.parse(Constants.UNSPLASH_URL).newBuilder();
          urlBuilder.addQueryParameter(Constants.UNSPLASH_CLIENT_ID, Constants.UNSPLASH_ID);
          String url = urlBuilder.build().toString();
          OkHttpClient client = new OkHttpClient.Builder()
                  .build();
          Request request= new Request.Builder()
                  .url(url)
                  .build();
          Call call = client.newCall(request);
          call.enqueue(callback);
      }
  ...
  </code></pre>
  
  <p>My getFoodPictures method on Main Activity. <code>getPictures</code> from UnSplash service goes into setting recyclerView on a <code>Runnable</code> callback on <code>runOnUiThread</code></p>
  
  <pre><code>public void getFoodPictures(){
          mOpenDescribe = this;
          final UnSplashService unSplashService = new UnSplashService();
          unSplashService.getPictures(new Callback() {
              @Override
              public void onFailure(Call call, IOException e) {
              }
              @Override
              public void onResponse(Call call, Response response) {
                       mPictures = unSplashService.processResults(response);
                       MainActivity.this.runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
                            mAdapter = new PictureListAdapter(mOpenDescribe, getApplicationContext
                                    (), mPictures, userFoods);
                              AlphaInAnimationAdapter animateAdapter = new AlphaInAnimationAdapter(mAdapter);
                              animateAdapter.setDuration(1500);
                              mPictureRecycleView.setAdapter(new AlphaInAnimationAdapter(animateAdapter));
                              mPictureRecycleView.setHasFixedSize(true);
                          }
                      });
                  }
              });
      }
  </code></pre>
  
  <p>My <code>getUserFood</code> Firebase method. On Main activity. </p>
  
  <pre><code>public void getUserFoods(){
          final ArrayList&lt;Picture&gt; tempUserFoods = new ArrayList&lt;&gt;();
          String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
          DatabaseReference ref = FirebaseDatabase.getInstance().getReference(Constants.FIREBASE_CHILD_DESCRIBED_FOODS).child(uid);
          ref.addListenerForSingleValueEvent(new ValueEventListener() {
              @Override
              public void onDataChange(DataSnapshot dataSnapshot) {
                  Log.d("Snapshot", dataSnapshot.toString());
                  for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                      tempUserFoods.add(snapshot.getValue(Picture.class));
                  }
                  userFoods = tempUserFoods;
                  getFoodPictures();
              }
              @Override
              public void onCancelled(DatabaseError databaseError) {
              }
          });
      }
  </code></pre>
  
  <p>onCreate in Main, I call <code>createAuthStateListener();</code> to check for user login. 
  Here, <code>getUserFoods()</code> is called. </p>
  
  <pre><code>public void createAuthStateListener(){
          mAuthListener = new FirebaseAuth.AuthStateListener() {
  
              @Override
              public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                  final FirebaseUser user = firebaseAuth.getCurrentUser();
                  if (user != null){
                      getUserFoods();
                      getSupportActionBar().setTitle(user.getDisplayName()+", you hungry?");
                  } else {
                      getSupportActionBar().setTitle("");
                  }
                  mAdapter.showHideFoodListener();
              }
          };
      }
  </code></pre>
  
  <p>Here is my adapter for RecyclerView</p>
  
  <pre><code>public class PictureListAdapter extends RecyclerView.Adapter&lt;PictureListAdapter.PictureViewHolder&gt; {
      private ArrayList&lt;Picture&gt; mPictures = new ArrayList&lt;&gt;();
      private Context mContext;
      private OpenDescribeFragment mOpenDescribe;
      public FirebaseAuth mAuth;
      public ArrayList&lt;Picture&gt; mUserFoods;
  
      public PictureListAdapter() { }
  
      public PictureListAdapter (OpenDescribeFragment listener, Context context, ArrayList&lt;Picture&gt;
              pictures, ArrayList&lt;Picture&gt; userFoods){
          super ();
          mOpenDescribe = listener;
          mContext = context;
          mPictures = pictures;
          mUserFoods = userFoods;
      }
  
      public class PictureViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
  
          @Bind(R.id.pictureItemView)
          ImageView mPictureView;
          @Bind(R.id.findFoodButton)
          ImageButton mFindFoodButton;
          @Bind(R.id.descriptionTextView)
          TextView descriptionTextView;
          private Context context;
  
          public PictureViewHolder(View itemView)   {
              super(itemView);
              ButterKnife.bind(this, itemView);
              mContext = itemView.getContext();
              mFindFoodButton.setOnClickListener(this);
              mAuth = FirebaseAuth.getInstance();
          }
  
          public void bindPicture(Picture picture) {
              Picasso.with(mContext).load(picture.getImageUrl()).into(mPictureView);
              if (mAuth.getCurrentUser() == null){
                  mFindFoodButton.setVisibility(View.INVISIBLE);
              } else {
                  mFindFoodButton.setVisibility(View.VISIBLE);
              }
  
          }
  
          @Override
          public void onClick(View v) {
              if(v == mFindFoodButton) {
                  mOpenDescribe.openDescribeFragment(v, mPictures.get(getAdapterPosition()));
              }
          }
  
      }
      @Override
      public PictureViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.picture_list_item, parent, false);
          PictureViewHolder viewHolder = new PictureViewHolder(view);
          return viewHolder;
      }
  
      @Override
      public void onBindViewHolder(PictureViewHolder holder,  int position) {
          holder.bindPicture(mPictures.get(position));
          Log.d("Size of User Foods", Integer.toString(mUserFoods.size()));
  
      }
  
      public void showHideFoodListener() {
          notifyDataSetChanged();
      }
  
      @Override
      public int getItemCount() {
          return mPictures.size();
      }
  }
  </code></pre>