How to listen to changes in Firebase database collection?

Viewed 542

I have the following code:

someDocumentRef.collection("data").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {

    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            RelativeLayout emptyLayout = fragmentView.findViewById(R.id.empty_layout);
            if (task.getResult() == null || task.getResult().isEmpty()) {
                emptyLayout.setVisibility(View.VISIBLE);
                rv.setVisibility(View.GONE);
            } else {
                Map<Character,List<QueryDocumentSnapshot>> dataDoc = new HashMap<>();
                for (QueryDocumentSnapshot document : task.getResult()) {
                    char letter = getFirstLetter(document.getString("full_name"));
                    List<QueryDocumentSnapshot> l = dataDoc.get(letter);
                    if (l == null) {
                        l = new ArrayList<>();
                        l.add(document);
                        dataDoc.put(letter, l);
                    } else {
                        l.add(document);
                    }
                }

                // Create recycler view
                emptyLayout.setVisibility(View.GONE);
                rv.setVisibility(View.VISIBLE);
                adapter = new DataAdapter(getActivity(), dataDoc);
                rv.setLayoutManager(new LinearLayoutManager(getActivity()));
                rv.setAdapter(adapter);
            }
        }
    }
});

In my onCreateView method (Fragment). Basically, it gets all documents from the collection data of the Firebase database and passes it to the adapter in order to create a recycler view. Works great but my question is how to listen to changes in the database and once some new document inserted or removed, update the recycler view? Note that I don't use the FirestoreRecyclerAdapter adapter, rather my custom adapter. Also, I'm using Firebase Cloud database.

1 Answers

You can actually listen to changes in firebase, sorry for the earlier comment. I checked fire store documentations and I saw this

final DocumentReference docRef = 
db.collection("cities").document("SF");
docRef.addSnapshotListener(new 
 EventListener<DocumentSnapshot>() {
  @Override
  public void onEvent(@Nullable DocumentSnapshot 
 snapshot,
                    @Nullable FirebaseFirestoreException e) {
    if (e != null) {
        Log.w(TAG, "Listen failed.", e);
        return;
    }

    if (snapshot != null && snapshot.exists()) {
        Log.d(TAG, "Current data: " + snapshot.getData());
    } else {
        Log.d(TAG, "Current data: null");
      }
   }
 });

Referenced from https://firebase.google.com/docs/firestore/query-data/listen

I hope it helps

Edit To listen to the whole collection:

    db.collection("cities")
    .addSnapshotListener(new 
     EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value,
                            @Nullable FirebaseFirestoreException e) 
           {
            if (e != null) {
                Log.w(TAG, "Listen failed.", e);
                return;
            }

            List<String> cities = new ArrayList<>();
            for (QueryDocumentSnapshot doc : value) {
                if (doc.get("name") != null) {
                    cities.add(doc.getString("name"));
                }
            }
            Log.d(TAG, "Current cites in CA: " + cities);
        }
      });

This will definitely listen to the whole collection. Reference: https://stackoverflow.com/a/48608816/8714139

Edit this how you'll get ur values

        Map<Character,List<QueryDocumentSnapshot>> dataDoc = new HashMap<>();
            for (QueryDocumentSnapshot document : value) {
                char letter = getFirstLetter(document.getString("full_name"));
                List<QueryDocumentSnapshot> l = dataDoc.get(letter);
                if (l == null) {
                    l = new ArrayList<>();
                    l.add(document);
                    dataDoc.put(letter, l);
                } else {
                    l.add(document);
                }
            }
Related