Issue
I am using both the Realtime Database and Firestore in my social media application, am currently only using the Realtime Database for storing the user details and for messaging while in the Firestore I have a status videos collection that has details of the status video and a field that stores the id of the user who posted it, As status videos are being fetched ...the id is obtained and put into an array so that I can use each id to fetch the user details from the Realtime Database, The challenge is that every time I try to fetch details of the user it only makes one call in the onBindView method and one view only receives the data fetched from the realtime database in terms of the name and profile picture...is there a way alternatively to make calls in line with the number of datasets I have to ensure that data is fetched for all Ids in the array?
here is the code from my main activity:
private void getStatusVid() {
database.collection(Constants.KEY_STATUS)
.limit(25)
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull @NotNull Task<QuerySnapshot> task) {
if(task.isSuccessful()&& task.getResult()!=null){
for (QueryDocumentSnapshot queryDocumentSnapshot:task.getResult()){
mVidsList.add(new StatusVids(queryDocumentSnapshot.getString(Constants.KEY_USER_ID),queryDocumentSnapshot.getString(Constants.KEY_COVER),queryDocumentSnapshot.getString(Constants.KEY_NAME),queryDocumentSnapshot.getString(Constants.KEY_TITLE),""));
}
if(mVidsList.size()>0){
mRecyclerVids.setAdapter(new StatusVidsAdapter(mVidsList,getActivity()));
}
}
}
});
}
and here is the code being exexuted in onBindView:
mRef.child(Constants.KEY_COLLECTION_USERS).child(mList.get(position).userId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull @NotNull DataSnapshot snapshot) {
for(DataSnapshot snappy: snapshot.getChildren()){
}
if(snapshot.exists()){
final String pictureUrl=snapshot.child("profile").getValue(String.class);
Glide.with(context)
.load(pictureUrl)
.circleCrop()
.into(holder.profile);
}
}
@Override
public void onCancelled(@NonNull @NotNull DatabaseError error) {
Toast.makeText(context,error.getMessage(),Toast.LENGTH_SHORT).show();
}
});
Solution
in short am avoiding continuously putting the user's profile image and name in every status video document because they are times users update images and the images in the status videos would be outdated.
In that case, you should update the name and the image inside all videos. It's true that might be some kind of costly since you need to update those values in each place it exists, but that's a requirement when you hold them there.
Another solution would be to only hold a reference that points to the user profile, a case in which you'll need to create another database call, in order to display the user data.
So it's always a trade, so you need to calculate which one of the solutions works best for you.
Answered By - Alex Mamo
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)