Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore where 'array-contains' query doesn't work with references

I have a collection 'chats' with a members array which contains users participating in the chat. The problem is I want to get all chats where the current user is participating.

I do this with this query:

getUserChats(): Observable<Chat[]> {
    return this.auth.currUser
      .pipe(
        take(1),
        switchMap(user => this.afs
            .collection('chats', ref => ref.where('members', 'array-contains', `/users/${user.uid}`))
            .snapshotChanges()
            .pipe(
              map(actions => {
                return actions.map(action => {
                  const data = action.payload.doc.data() as Chat;
                  const id = action.payload.doc.id;
                  return {id, ...data};
                });
              })
            ) as Observable<Chat[]>
        )
      );
  }

This works well for strings, but doesn't work with References. How can I also make it work on References?

Image with Collections

The green works the red one doesn't work

Green: String Red: Reference

like image 790
filip Avatar asked Nov 08 '18 09:11

filip


2 Answers

@Alex Mamo answer is right, you need a DocumentReference.

NOTE: YOU CAN'T CREATE ONE YOURSELF!

You have to get the reference by querying firebase!

Code:

return this.auth.currUser
      .pipe(
        take(1),
        switchMap(user => this.afs
            .collection('chats', ref => ref.where('members', 'array-contains', this.afs
              .collection('users')
              .doc<User>(user.uid)
              .ref))
            .snapshotChanges()
            .pipe(
              map(actions => {
                return actions.map(action => {
                  const data = action.payload.doc.data() as Chat;
                  const id = action.payload.doc.id;
                  return {id, ...data};
                });
              })
            ) as Observable<Chat[]>
        )
      );

The crucial part is the 'value' part which is:

this.afs
              .collection('users')
              .doc<User>(user.uid)
              .ref

You query and THEN get the reference with .ref!

That's it! That's how you query for a DocumentReference!

like image 130
filip Avatar answered Oct 21 '22 22:10

filip


It works with strings because you're passing as the third argument to the where() function the following argument:

/users/${user.uid}

Which is of type String. If you want to work with references as well, instead of a String, pass an actual DocumentReference object.

like image 5
Alex Mamo Avatar answered Oct 21 '22 22:10

Alex Mamo