Firebase 有时只提供我保存的部分值,有时提供所有值

Firebase gives sometimes only parts of my saved values and sometimes everything

我正在尝试编写自己的 Messenger。我将消息保存在 Firebase 数据库中。我正在尝试以正常方式访问消息,我每次都是这样做的(database.database().reference().child("users").....,但它只返回一个很少的消息,有时只有每条消息

我已经用 .childAdded 试过了,但它也不起作用

func fetchMessages() {
        self.messages.removeAll()
        let uid = Auth.auth().currentUser!.uid
        let ref = Database.database().reference().child("users").child(uid).child("chats").child(self.chatuid).child("messages")
        ref.observeSingleEvent(of: .value) { (snap) in
            guard let data = snap.value as? [String: AnyObject] else { return }
            //MARK: data = (messageID, AnyObject)
            for (messageID, _) in data {
                ref.child(messageID).observeSingleEvent(of: .value) { (snap2) in
                    guard let data2 = snap2.value as? [String: AnyObject] else { return }
                    //MARK: data2 = ("message": String, "sentuid": String)
                    guard let message = data2["message"] as? String else { return }
                    guard let sentuid = data2["sentuid"] as? String else { return }
                    let messageToAppend = Message(sentuid: sentuid, message: message)
                    self.messages.append(messageToAppend)
                    self.messageTableView.reloadData()
                }
            }
        }
    }

//self.messages = Place where I save my fetched messages

Firebase 结构:

{


"users" : {
    "V3bLZu61KYTCG0uCWV8LH1f4rRJ3" : {
      "chats" : {
        "x3GzxwmyLbXrQNNyBF2a82KqrHa2" : {
          "messages" : {
            "20191014165454" : {
              "message" : "Heyho",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165647" : {
              "message" : "Blabla",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165754" : {
              "message" : "Blabla",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165800" : {
              "message" : "Fuchsloch",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165805" : {
              "message" : "Jlksaö",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165808" : {
              "message" : "Jadfsk",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165811" : {
              "message" : "Jskldflsö",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014170041" : {
              "message" : "JALSF",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "test" : {
              "messange" : "test",
              "sentUid" : "MatesForSports"
            }
          }
        }
      },
      "username" : "Acc2"
    },
    "x3GzxwmyLbXrQNNyBF2a82KqrHa2" : {
      "chats" : {
        "V3bLZu61KYTCG0uCWV8LH1f4rRJ3" : {
          "messages" : {
            "20191014165454" : {
              "message" : "Heyho",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165647" : {
              "message" : "Blabla",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165754" : {
              "message" : "Blabla",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165800" : {
              "message" : "Fuchsloch",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165805" : {
              "message" : "Jlksaö",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165808" : {
              "message" : "Jadfsk",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014165811" : {
              "message" : "Jskldflsö",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "20191014170041" : {
              "message" : "JALSF",
              "sentuid" : "V3bLZu61KYTCG0uCWV8LH1f4rRJ3"
            },
            "test" : {
              "messange" : "test",
              "sentUid" : "MatesForSports"
            }
          }
        }
      },
      "username" : "Acc1"
    }
  }
}

我预计该代码会返回大约 10 条消息,但它有时会返回 5 条、有时 3 条甚至仅 2 条消息

我的消息的 firebase 结构是 .child("messages"),然后是唯一 ID,然后是实际消息和一层的发件人

这是一个答案和一个建议。

让我们从使用一些硬编码值复制您的结构开始

users
   uid_0
      chats
         chat_uid_0
           messages
              unique_id_0
                 msg: "My Message"
                 sent_uid: "uid_1"
              unique_id_1
                 msg: "Hello, World"
                 sent_uid: "uid_3"
              unique_id_2
                 msg: "another message"
                 sent_uid: "uid_2"

然后是读取消息的代码,遍历它们并打印出消息和 sent_uid

func readMessages() {
    let usersRef = self.ref.child("users")
    let messagesRef = usersRef.child("uid_0").child("chats").child("chat_uid_0").child("messages")
    messagesRef.observeSingleEvent(of: .value, with: { snapshot in
        let allMessages = snapshot.children.allObjects as! [DataSnapshot]
        for msg in allMessages {
            let msgText = msg.childSnapshot(forPath: "msg").value as? String ?? "No Msg"
            let sentUid = msg.childSnapshot(forPath: "sent_uid").value as? String ?? "No sender"
            print(msgText, sentUid)
        }
    })
}

输出为

My message uid_1
Hello, World uid_3
another message uid_2

话虽这么说 - 你的结构太深了,应该去规范化。虽然它可能会起作用,但一旦您想查询项目或查找特定用户发布的消息,它就不起作用了。

我不知道您的完整用例,但这会是一个更好的结构

users
   uid_0
      name: "Hank"
   uid_1
      name: "Leroy"

chats
   uid_0
      chat_id_0: true
      chat_id_1: true
   uid_1
      chat_id_5: true

chat_id_0
   unique_id_0
      msg: "My Message"
      sent_uid: "uid_1"
   unique_id_1
      msg: "Hello, World"
      sent_uid: "uid_3"
   unique_id_2
      msg: "another message"
      sent_uid: "uid_2"

使用这种结构,一切都非常浅,很容易获取数据 - 执行查询等。您可以快速检索 uid_0 涉及的所有聊天,获取 uid_3 曾经的任何消息在 uid_1 的聊天中发布或添加观察员,以便在添加聊天时通知其他人。同样,这只是一个示例,可能不适合您的情况,但值得考虑。