簡體   English   中英

繞過Firebase IN: limit in Swift

[英]Bypassing Firebase IN: limit in Swift

我有一個查詢,我正在使用 Google 的 Firestore 進行查詢,在那里我從一個集合中查詢帖子。 這是 .network 上所有帖子的中央集合,但我希望能夠過濾來自服務器的內容,這樣處理/過濾就不會在客戶端發生。 本質上,我只想從用戶關注的帳戶中獲取帖子提要。

創建該數組很容易。 當用戶登錄時,它會下載用戶遵循的 UID 數組。 從理論上講,這個數組可能很長。 Firestore 有這個方便的“.whereField”選項,可以像這樣使用 in: 過濾字符串數組的外觀。

.whereField("userUID", in: auth.userFollowedAccounts!)

它工作得很好,但根據文檔,當使用 in: 時,Firestore 只允許數組中的 10 個項目。 這會導致問題,因為我希望用戶能夠關注 10 個以上的帳戶。 我看到了一些其他語言的其他解決方案,通過拼接數組或通過所有選項對 go 進行一些巧妙的循環來解決這個問題。 不幸的是,我似乎找不到 Swift 的解決方案。希望有人能幫我集思廣益解決這個問題。

// 完整代碼塊

    func getData() {
    let db = Firestore.firestore()
    db.collection("posts")
        .order(by: "dateCreated", descending: true)
        .whereField("userUID", in: auth.userFollowedAccounts!)
        .limit(to: 10)
        .getDocuments { (snap, err) in
        
        if err != nil {
            print((err?.localizedDescription)!)
            return
        }
        
        self.post.removeAll()
        
        for i in snap!.documents {
            let data = Post(id: i.documentID, username: i.get("username") as? String, fullName: i.get("fullName") as? String, profilePictureURL: i.get("profilePictureURL") as? String, link: i.get("link") as? String, location: i.get("location") as? String, postImage: i.get("postImage") as? String, isVerified: i.get("isVerified") as? Bool, caption: i.get("caption") as? String, likeCounter: i.get("likeCounter") as? Int, dateCreated: i.get("dateCreated") as? String, userUID: i.get("userUID") as? String, isAdmin: i.get("isAdmin") as? Bool, pronouns: i.get("pronouns") as? String)
            
                self.post.append(data)
        }
        
        self.lastDoc = snap!.documents.last
    }
}

如果您有任何問題,請告訴我。

下面是一個使用 Firestore async/await 調用來縮短代碼的簡單示例。

問題中未包含 Firebase 結構(請在問題中包含該結構),因此我將制作一個可能與您使用的結構相似的結構

從使用用戶 uid 作為 documentId 的用戶集合開始,保留用戶名,然后將他們關注的用戶作為數組

users
   uid_0
      user_name: "Leroy"
      following
          0: uid_9
   uid_1
      user_name: "Biff"
      following
          0: uid_0
          1: uid_2

在此,uid_0 跟隨 uid_9,uid_1 跟隨 uid_0 和 uid_2

然后是一個帖子集合片段

posts
   post_0
      post_msg: "Post 0 from uid_0"
      post_uid: "uid_0"
   post_1
      post_msg: "Post 0 from uid_1"
      post_uid: "uid_1"
   post_2
      post_msg: "Post 1 from uid_0"
      post_uid: "uid_0"

這些帖子有一條消息和發布它的用戶的 uid。

然后是代碼。

func getPostsOfUsersIFollow() {
    let usersCollection = self.db.collection("users")
    let postsCollection = self.db.collection("posts")
    let thisUserDoc = usersCollection.document("uid_1") //me
    
    Task {
        do {
            let userResult = try await thisUserDoc.getDocument()
            let usersIFollow = userResult.get("following") as? [String] ?? []
            
            print(usersIFollow) //outputs the list of users uid's I follow
            
            for uid in usersIFollow {
                let usersPosts = try await postsCollection.whereField("post_uid", isEqualTo: uid).getDocuments()
                for postDoc in usersPosts.documents {
                    let postMsg = postDoc.get("post_msg") as? String ?? "no msg"
                    print("post_id: \(postDoc.documentID)   uid: \(uid) posted msg: \(postMsg)")
                }
            }
        } catch {
            print("need to handle error")
        }
    }
}

如果我是用戶 uid_1,那么我關注的是 uid_0 和 uid_2。 運行此代碼時,它將首先查詢我關注的所有用戶(uid_0、uid_2),然后遍歷該列表(可以是任意數量的用戶)以查詢每個用戶的帖子,以及 output 那些發布到控制台。

因此,如果 uid_0 有 3 個帖子而 uid_2 有 3 個帖子,那么最終的 output 將如下所示

["uid_0", "uid_2"]
post_id: post_0   uid_0 posted msg: Post 0 from uid_0
post_id: post_4   uid_0 posted msg: Post 1 from uid_0
post_id: post_6   uid_0 posted msg: Post 2 from uid_0
post_id: post_2   uid_2 posted msg: Post 0 from uid_2
post_id: post_5   uid_2 posted msg: Post 1 from uid_2
post_id: post_9   uid_2 posted msg: Post 2 from uid_2

在這種情況下,我 output 進行控制台,但在代碼中,您可能有一些 class 來存儲 uid、名稱和發布,然后填充一個數組,該數組支持 tableView 或使用該數據的集合

class UserPostClass {
   var uid = ""
   var postId = ""
   var userName = ""
   var postMsg = ""
}

var userPostArray = [UserPostClass]()

然后一旦數組被填充,重新加載你的 tableView,視圖等。

這里的一個問題是確保 UI 是響應式的——對於小型數據集,這將按原樣工作,但如果您要加載數千篇文章(不要那樣做),您可能需要對數據進行分頁以將其分成更小的塊。

另一件需要注意的事情是沒有排序,所以你可能想要添加一個 orderBy 子句

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM