firebase 调用一个异步查询,该查询依赖于对firestore的另一个异步调用

6jygbczu  于 2023-01-05  发布在  其他
关注(0)|答案(2)|浏览(107)

我一直在尝试在我的swift应用程序中使用firestore实现一个基本的关注者订阅系统,我已经为firestore设置了三个顶级集合:用户、评论和评论。我希望用一组特定用户发布的最新评论来填充我的提要。为此,我首先需要从Users集合(我当前关注的用户)中获取该组用户,然后使用这些用户(我关注的用户)的documentID从Reviews集合(我关注的每个用户3条最新评论)中获取相应的评论。
然而,由于通过SDK的调用是异步的,我很难先获取用户,然后再为我的提要获取评论。我对异步相当陌生,尽管我已经对swift中的并发有了一些透彻的理解,但我仍在等待。有人能给我指出正确的方向吗?
获取用户的代码如下所示:

private func fetchReviews(for userID: String) {
    let reviewRef = FirebaseManager.shared.firestore.collection("Reviews")
    
    reviewRef
      .whereField("uid", isEqualTo: userID)
      .order(by: "createdAt", descending: true)
      .limit(to: 3)
      .getDocuments { querySnapshot, error in
        guard let documents = querySnapshot?.documents, error == nil else { return }
        
        reviews = documents.compactMap({ queryDocumentSnapshot in
          try? queryDocumentSnapshot.data(as: Review.self)
        })
      }
  }

如果我定义一个函数来获取我当前关注的用户:

// Fetches all users I follow and stores it in the usersIFollow var.
  private func fetchUsersIFollow() {

    // fetch the "following" subcollection within the current user's document.
    guard let userID = FirebaseManager.shared.auth.currentUser?.uid else { return }
    let db = FirebaseManager.shared.firestore
    db.collection("Users").document(userID).collection("Following").getDocuments { querySnapshot, error in
      guard let documents = querySnapshot?.documents, error == nil else { return }

      usersIFollow = documents.compactMap { queryDocumentSnapshot in
        try? queryDocumentSnapshot.data(as: User.self)
      }
    }
  }

(其中用户I关注:[User]是一个状态变量),然后在fetchReviews()方法中调用它,如下所示

private func fetchReviews(for userID: String) {
    fetchUsersIFollow() 
    let reviewRef = FirebaseManager.shared.firestore.collection("Reviews")
    
    reviewRef
      .whereField("uid", isEqualTo: userID)
      .order(by: "createdAt", descending: true)
      .limit(to: 3)
      .getDocuments { querySnapshot, error in
        guard let documents = querySnapshot?.documents, error == nil else { return }
        
        reviews = documents.compactMap({ queryDocumentSnapshot in
          try? queryDocumentSnapshot.data(as: Review.self)
        })
      }
  }

因为都是异步调用,所以不起作用。我该如何调整它?
注:我知道这可能不是处理feed系统的最佳方式,它只是一个基本实现,我将在开发应用程序时进一步修改它。

ws51t4hk

ws51t4hk1#

您可以采取两种方法:
1.在fetchFollowersgetDocuments闭包中调用fetchReviews
1.使用异步版本的getDocuments,使fetchFollowersfetchReviews异步,然后从Task块中以正确的顺序调用它们。任务用于通过在单独的线程上运行它来从同步代码中调用异步代码。
(1)闭包方法的伪代码:

fetchFollowerReviews() {
   configure followersRef

   followersRef.getDocuments { 
      followers = safely unwrapped snapshot

      configure reviewsRef using followers ids
      reviewsRef.getDocuments {
         reviews = safely unwrapped snapshot
         handle reviews data
      }
   }
}

(2)异步方法的伪代码:

fetchFollowerReviews() {
   Task {   
      let followers = try await fetchFollowers()
      let reviews = try await fetchReviews(from: followers)
      handle reviews
   }
}

fetchFollowers() async throws -> [Follower] {
   configure docRef
   let snapshot = try await docRef.getDocuments()
   followers = safely unwrapped snapshot
   return followers
}

fetchReviews(from: followers) async throws -> [Reviews] {
   configure docRef using followers ids
   let snapshot = try await docRef.getDocuments()
   reviews = safely unwrapped snapshot
   return reviews
}
ny6fqffe

ny6fqffe2#

我认为您可以使用闭包来获取您首先关注的用户,然后使用他们的文档ID来获取他们的评论,

private func fetchFollowers(completion: @escaping ([String]) -> Void) {
  let followersRef = FirebaseManager.shared.firestore.collection("Users")
  
  followersRef
    .whereField("uid", isEqualTo: userID)
    .getDocuments { querySnapshot, error in
      guard let documents = querySnapshot?.documents, error == nil else { return }
      
      let followerIDs = documents.compactMap({ queryDocumentSnapshot in
        return queryDocumentSnapshot.documentID
      })
      
      completion(followerIDs)
    }
}

//your fetchReviews function will go here as it
private func fetchFeed() {
  fetchFollowers { followerIDs in
    for followerID in followerIDs {
      fetchReviews(for: followerID)
    }
  }
}

这样,您就可以首先获取关注的用户,然后使用他们的文档ID获取他们的评论。

相关问题