是否可以从实时数据库中获取添加的最后一个密钥(最新消息)?

我想从我的实时数据库中获取最后一个密钥(最新消息),但不确定如何实现。 我从这个链接 i need to get Last child of my firebase databse 看到我可以使用 orderByKey().limitToLast(1) 来获得它,但看起来我需要指定完整的 ref 才能实现这一点。那是对的吗?或者是否可以在 val() 上 orderByKey().limitToLast(1) ?或者有另一种方法可以实现这一目标吗? 这是我在数据库中的消息结构:

是否可以从实时数据库中获取添加的最后一个密钥(最新消息)?

是否可以从实时数据库中获取添加的最后一个密钥(最新消息)?

我在每个键下都有一个时间戳子项,如上所示,我以为我可以查询以提取最新的键,但我真的不知道该怎么做。有人可以帮忙吗?以下是我目前的代码:

database().ref(`messages/`).once(`value`,snapshot => {
 if(snapshot.exists()) {
   snapshot.forEach(function (childsnapshot) {
      if(childsnapshot.key.includes(auth().currentUser.uid)) {
      console.log("show me the key: "+childsnapshot.key)

      //not working
      console.log("show last message: "+ JSON.stringify(childsnapshot.val().orderbyKey().limitToLast(1)))
      }
    })
  }
})

console.log(JSON.stringify(messages)) => [{"-MfqYBzbusp1Cljgxpan":{"unreadMessage":true,"user":{"name":"Mike","avatar":"xxxxxx","_id":"tFhmw5oQoPhk8nF2sx5rE5BFqw93"},"timestamp":1627634061437,"senderId":"tFhmw5oQoPhk8nF2sx5rE5BFqw93",""Project","image:"{yUrHe","image:"{ ./assets/xxxxx.png"},"text":"嘿"}}]

console.log(JSON.stringify(unreadMsgs)) => []

skywwh123 回答:是否可以从实时数据库中获取添加的最后一个密钥(最新消息)?

orderByKeylimitToLast 方法存在于 DatabaseReference 中,而不存在于您从之前获取的快照中获取的值中。似乎所有消息的父键都是 userId1userId2 格式。如果您知道这种组合,那么您就可以这样运行查询。

const uidsKey = "uid1" + "uid2"
const query = database().ref(`messages/${uidsKey}`).orderByChild("timestamp").limitToLast(1)

query.once("value").then((snapshot) => {
  console.log(snapshot.val())
})

但您似乎正在尝试获取与 user1 聊天的其他用户的 UID,并尝试首先真实所有节点。我不建议这样做,因为这可能会导致安全规则等方面的问题。相反,如果您将这些 UID 列表保留在其他地方,那会更好。但是如果你想保留你现在拥有的东西,试试这个:

const userUID = auth().currentUser.uid

database().ref("messages/").once("value").then(async (msgSnapshot) => {
  const keys = Object.keys(msgSnapshot.val() || {})
  const userChatKeys = keys.filter(k => k.includes(userUID))
  //const otherUserIDs = userChatKeys.map(k => k.replace(userUID,""))

  //userChatKeys will be chat IDs where current user is included
  //now follow the same steps mentioned in first code snippet
  const queries = userChatKeys.map(chat => database().ref(`messages/${chat}`).orderByChild("timestamp").limitToLast(1).once("value"))
  const lastMessagesSnap = await Promise.all(queries)
  
  const messages = lastMessagesSnap.map(m => Object.values(m.val())[0])) 
  console.log(`messages: ${messages}`)
  const unreadMsgs = messages.filter((msg) => msg.unreadMessage === true)
  console.log(unreadMsgs.length)
})

这将记录每个用户聊天的最后一条消息。

,

Firebase 实时数据库查询在节点的平面列表上工作。因此,如果您已有特定路径 /messages/nodeid,则可以在该路径下找到最新消息,但无法在所有 /messages 中找到最新消息。

阅读来自所有聊天室的所有消息,只是为了找到该用户所在的每个聊天室的最新消息确实很浪费。随着您向应用添加更多用户,您会增加他们和您自己的带宽成本。

我建议保留一个单独的节点,您可以在其中跟踪每个用户的聊天室,如我在 Best way to manage Chat channels in Firebase 上的回答中所述。使用这样的节点,您可以轻松地确定当前用户的聊天室,然后为每个人加载最新消息,例如:

database().ref(`user_chatrooms/${auth().currentUser.uid}`).once(`value`,indexSnapshot => {
  indexSnapshot.forEach((indexSnapshotChild) => {
    let chatroomId = indexSnapshotChild.key;
    let query = database().ref(`messages/${chatroomId}`).orderByChild("timestamp").limitToLast(1)
    query.once(`value`,(msgSnapshot) => {
      console.log(`Last message in ${chatroomId} was ${msgSnapshot.val().text}`);
    })
  }
})
本文链接:https://www.f2er.com/2834.html

大家都在问