0

The picture below shows the data structure for the simple chat application. A channel is created between two users when they want to communicate. Member string array field lists the usernames.

I want to notify the user when any of the channels of logged in user receive a message. Not sure how this can be done.

I tried below query with no success. Any ideas?

    listenerRegistration2 =
            firebaseFirestore.collection(COLLECTION_CHANNELS)
                    .whereEqualTo("members.0", username)
                    .addSnapshotListener((queryDocumentSnapshots, e) -> {
                        Log.d("myApp", "queryDocumentSnapshots = ");
                    });

enter image description here

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Patola
  • 515
  • 8
  • 30
  • How do you want to notify the user? – Alex Mamo Jul 31 '18 at 10:01
  • If you want to send a notification, note that I have exaplained in one of my **[tutorials](https://www.youtube.com/playlist?list=PLn2n4GESV0AmXOWOam729bC47v0d0Ohee)** step by step, how you can send **[notifications](https://www.youtube.com/watch?v=6RzB4HXzQyA&t=3s&list=PLn2n4GESV0AmXOWOam729bC47v0d0Ohee&index=17)** to specific users using Cloud Firestore and Node.js. – Alex Mamo Jul 31 '18 at 10:01
  • I am planing to use above code and listen on background service and then notify the user when listener call back is executed. The only problem I am facing is how to write a query with the current data model. – Patola Jul 31 '18 at 10:09
  • I understand now. I'll write you an answer right now. – Alex Mamo Jul 31 '18 at 10:17

1 Answers1

1

Edit: September 12, 2018

Starting with August 28, 2018, now it's possible to update array members. More informations here.


As in the official documentation regarding arrays:

Although Cloud Firestore can store arrays, it does not support querying array members or updating single array elements.

So unfortunately you cannot achieve this using arrays. If you only want to get the entire memebers array, just use a get() call and then only to iterate over a Map like this:

Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
    if (entry.getKey().equals("memebers")) {
        Log.d("TAG", entry.getValue().toString());
    }
}

But note, even if memebers object is stored in the database as an array, entry.getValue() returns an ArrayList, not an array.

There is also an workaround here, that can help you achieve this but you need to change the memebers array property to a map. So a better approach will be if you consider this alternative database structure, where each memeber is the key in a map and all values are true:

memebers: {
    "sister12": true,
    "wow": true
}
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thanks for the answer, how would you write a query to get/listen new messages in all channels related to a specific user /member. If current model does not support it what would be the best model and how would the query look like. – Patola Jul 31 '18 at 10:54
  • In this case, you should consider augmenting your data structure to allow a reverse lookup and for that I recommend you see one of my **[tutorials](https://www.youtube.com/playlist?list=PLn2n4GESV0AmXOWOam729bC47v0d0Ohee)** in which the shoppings lists are more likely chat rooms (channels), right? – Alex Mamo Jul 31 '18 at 12:00
  • In particular I recommend you see this episode [Database Structure](https://www.youtube.com/watch?v=idywm80Qbvc&t=15s&list=PLn2n4GESV0AmXOWOam729bC47v0d0Ohee&index=4). – Alex Mamo Jul 31 '18 at 12:02