Search code examples
swiftfirebasegoogle-cloud-firestore

Chaining x firebase queries together


I have a basic app built with swift and firebase where each post can be replied to with another post. These reply posts can have their own replies and so on. My database is set up as a tree where "Posttree" is the root of the tree and the first level is all the original posts. The replies to each original post is stored in a "reply" collection beneath each level 1 node.

Given an array of size x that represents the path to a document, how can I set up the query? How do I chain each call to .document(databaseLocation[0]).collection("replies")? Is there a better way to configure this setup in firebase database?

func getPost(){
    let documentToFetch = "wefjqnwocb2f"
    // example 
    let databaseLocation = ["ferfwerf", "3e239hdwedwb", "fn32h49ffnf"]
    
    // based on databaseLocation the query should be
    var query = db.collection("Posttree")
        .document(databaseLocation[0]).collection("replies")
        .document(databaseLocation[1]).collection("replies")
        .document(databaseLocation[2]).collection("replies")
        .document(documentToFetch)        
}

example

                              Posttree

           Post1                                      Post2

(Post1/reply1)  (Post1/reply2)                 (Post2/reply1)  (Post2/reply2)
                      |
              (Post1/reply2/reply1)

Solution

  • Having a nested structure like this is a common anti-pattern. Just because the database allows you to store hierarchies, doesn't mean that you should model a functional/content hierarchy in your data structure.

    My common rule of thumb is that each type of content should exist in one level in the hierarchy only.


    So if you have posts and replies, I'd expect to see posts on one level and replies on one other level. No nesting of replies.

    You can then build the content hierarchy by having each comment have a parent ID referring to their parent comment of post, or even an array of parent IDs.

    In fact, I'd typically not even separate posts and replies, but just have the "posts" collection(s) on one level only, and have a parent ID field in each that can be empty (for top-level posts).


    Having the content on one level makes it easier and more flexible to query.