0

I am trying to write a query to Firestore using reference type. I have checked documentation and some questions on the SO, but did not unerstood how to use references in where conditions. I do undestand that reference field can help me to get document that is referenced by it, because reference is a path. I have one to one structure and would like to get documents by it's reference in the "opposite" direction. In the same time I have other tables with one-to-many structure. And I want to use the same approach with them.

Here is my structure. It's one to one. One document in activeSessions collection must have only one respective document in tables collection:

Root collection
    |
    |
    -- tables (collection)
    |   |
    |   |
    |   -- tableName
    |   |
    |   -- tableCapacity
    |
    |
    -- activeSessions (collection)
        |
        |
        -- openTime
        |
        -- tableReference (reference that contains path to one of tables document.)

So I would like to get document from activeSessions collection that has a reference to document that I already have. I have tried the following function, but it returns a document for any table document.

class func getActiveSession (forTable table: TablesTable, completion: @escaping (TableSessionTable?, Error?) -> Void) {
    // table.firebaseID contains unique id of the table document.
    // let userData = appDelegate.db.collection("usersData").document(userId)
    let tableReference = userData.collection("tables").document(table.firebaseID!)
    print(table.firebaseID)
    print (tableReference)
    let tableSessionCollection = userData.collection("activeSessions")
    tableSessionCollection.whereField("tableReference", isEqualTo: tableReference)
    tableSessionCollection.addSnapshotListener { (snapshot, error) in
        if let error = error {
            completion(nil, error)
            return
        }

        if let snapshot = snapshot {

            let ref = data["tableReference"] as! DocumentReference
            print("tablesession reference is to \(ref.documentID)")
            print(ref)
            completion(tableSession, error)
        }
    }
}

According to this question everything should work fine. But it doesn't. I have put some prints into my function and as per the output, it returns one doc from tableSession query two times. It's reference references to the same documentID. But in the same time instances of DocumentReference object are different:

Optional("12tVcpi93aPbN8qWmtLx")
<FIRDocumentReference: 0x6000011e76e0>
Optional("s7FCXMlCdx61OmtHyQvy")
<FIRDocumentReference: 0x6000011e5b60>

tablesession reference is to s7FCXMlCdx61OmtHyQvy
<FIRDocumentReference: 0x6000011e3600>

tablesession reference is to s7FCXMlCdx61OmtHyQvy
<FIRDocumentReference: 0x60000119b4c0>
DJ-Glock
  • 1,277
  • 2
  • 12
  • 39

1 Answers1

1

This doesn't have anything to do with the fact that you're querying for a reference type field. The problem is that you're not building the query properly. You need to chain the filters together. Each added filter returns a new query object, and you need to build upon that new query.

let tableReference = userData.collection("tables").document(table.firebaseID!)
let tableSessionCollection = userData
    .collection("activeSessions")
    .whereField("tableReference", isEqualTo: tableReference)
tableSessionCollection.addSnapshotListener { (snapshot, error) in
    // ...
}

See also: Firestore: Multiple conditional where clauses

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441