首页 > 解决方案 > swift for循环数据顺序不正确

问题描述

我想从 firebase 获取数据并将它们放入一个数组中。函数的第一部分总是按正确的顺序排列,当我打印时我可以看到它(调试(文件)。但是在 for 循环之后,文档的顺序混乱,我总是得到随机顺序。我不应该总是得到相同的顺序?

func getUnreadMessages(){

    guard let uid = AuthViewModel.shared.userSession?.uid else {return}
    Firestore.firestore().collection("users").document(uid).collection("chats").order(by: "created", descending: true).getDocuments { (snapshot, _) in
        guard let files = snapshot?.documents.compactMap({ $0.documentID }) else {return}
        print("DEBUG: \(files)")
        
        for file in files{
            Firestore.firestore().collection("users").document(uid).collection("chats").document(file).collection("messages").whereField("read", isEqualTo: false).getDocuments { (snapshot, _) in
                guard let documents = snapshot?.documents.compactMap({ $0.documentID }) else {return}
                print("DEBUG: \(documents)")
                self.count.append(documents.count)
                print("DEBUG: \(self.count)")
            }
        }
    }
}

标签: swiftfirebasefor-loopgoogle-cloud-firestoreswiftui

解决方案


返回结果的顺序由order(by子句确定。否则结果可能看起来有些随机。

在这种情况下,第一个 Firebase 调用指定了一个顺序,因此这些文档将始终以正确的顺序返回。

collection("chats").order(by: "created"

但是下一个 firebase 调用没有指定顺序,因此返回的文档可能有点不一致。

.collection("messages").whereField

我们需要有一些方法来保证这个顺序。

假设结构是这样的

chats (collection)
   user ids (documents)
      chats (collection)
         chat ids (documents)
            messages (collection)
               message ids (documents that you want ordered)

消息 ID 需要有一个字段来对它们进行排序 - 调用它ordering

这是打印每个聊天 id 中消息数的计数然后按顺序打印消息的代码

func getUnreadMessages() {
    let uid = "uid_0"
    self.db.collection("users_chats").document(uid).collection("chats").getDocuments(completion: { snapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        guard let docs = snapshot?.documents else { return }

        for doc in docs {
            let ref = doc.reference.collection("messages")
            ref.order(by: "ordering").getDocuments(completion: { messagesSnapshot, error in
                if let err = error {
                    print(err.localizedDescription)
                    return
                }

                guard let messages = messagesSnapshot?.documents else { return }

                print("the chat document: \(doc.documentID) has \(messages.count) messages")
                for msg in messages {
                    let order = msg.get("ordering")
                    let msg = msg.get("read")
                    print("order: \(order!)", "is read: \(msg!)")
                }
            })
        }
    })
}

如果聊天 0 中有 3 条消息,则输出如下所示

the chat document: chat_0 has 3 messages
the chat document: chat_1 has 0 messages
the chat document: chat_2 has 0 messages
order: 0 isRead: 0
order: 1 isRead: 1
order: 2 isRead: 0

推荐阅读