skip to Main Content

I have a posts collection in Firebase which contains all the posts people make on my app and each document has its own "post-saves" and "post-likes" collection. when a user saves a post it adds their user ID to the "post-saves" collection within the post. I want to create a query to find all the posts that have the user’s id in the "post-saves" collection and then return the posts data, but with the user’s id being its document in the "post-saves" collection it just returns the user’s id.

static func FetchUserSavedPosts(uid: String) async throws -> [Post] {

    let docsnapshot = try await postsCollection.document().collection("post-saves").whereField("userid", isEqualTo: uid).getDocuments()
        return try docsnapshot.documents.compactMap({ try $0.data(as: Post.self) })
    
}

static func checkIfUsersavedPost(_ post: Post) async throws -> Bool {
    guard let uid = Auth.auth().currentUser?.uid else { return false }

    let snapshots = try await
    postsCollection.document(post.id).collection("post-saves").document(uid).getDocument()
    return snapshots.exists
}

//save post

static func savepost(_ post: Post) async throws {
    guard let uid = Auth.auth().currentUser?.uid else { return }
            
    let postRef = postsCollection.document(post.id).collection("post-saves").document(uid)
    
    let post = UserID(id: uid)
    
    guard let encodedPost = try? Firestore.Encoder().encode(post) else { return }
    
    async let _ = try await postRef.setData(encodedPost)
}
}

datastructure image

Please let me know if you need more details/clarity.

2

Answers


  1. You’re getting snapshot off nested collection post-saves. Do you try to query by posts with filter, like that:

    let docsnapshot = try await postsCollection.document().collection("posts").whereField("post-saves.userid", isEqualTo: uid).getDocuments()
    
    Login or Signup to reply.
  2. When you’re using the following query:

    postsCollection.document().collection("post-saves").whereField("userid", isEqualTo: uid)
    //                      👆
    

    It means that you’re trying to get all documents inside the post-saves sub-collection, where the userid field holds the value, of the UID, most likely of the authenticated user.

    In the code above, when you are not passing an ID to the .document() function, it means that you’re generating a brand new document ID instead of using the document ID that exists inside your collection. If you want to create a such a reference, you have to pass the ID of the document like below:

    postsCollection.document("3iKc...G2o3").collection("post-saves").whereField("userid", isEqualTo: uid)
    //                      👆
    

    To get the content of the highlighted document, if you already have that ID, then there is no reason to use a query. You can simply read the document using the following document reference:

    postsCollection.document("3iKc...G2o3").collection("post-saves").document("Puut...rM23")
    

    So both IDs are needed to create the reference. If there are multiple documents in the sub-collection, then indeed a query is needed. But keep in mind that the document inside the sub-collection should contain a field that holds that UID:

    postsCollection.document("3iKc...G2o3").collection("post-saves").whereField("userid", isEqualTo: uid)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search