首页 > 解决方案 > 在 Firebase 和 Javascript 中建立私人聊天

问题描述

我正在使用 Firebase 构建一个应用程序,该应用程序需要用户之间的私人消息传递。我需要的是为 1-1 聊天构建单个聊天,将消息存储在 Firestore 中。

我的想法:我想最好的方法是为每个聊天建立一个集合,并使用正确的安全规则。假设 tokenID 为 1234 的用户想要与 tokenID 为 1111 的用户交谈,将创建一个名为 1234_1111 的新集合(如果不存在),并且安全性将只允许这两个用户读写。

我的问题:这是正确的方法吗?以及如何在 Javascript 中做到这一点?我不确定如何直接在 JS 代码中定义安全规则,也不确定如何使用两个用户 ID 创建一个集合。

标签: javascriptfirebasegoogle-cloud-firestorefirebase-security

解决方案


安全规则未在您的 JavaScript 代码中定义,它们是单独定义的。尽管我会为此使用子集合,但您的建议将是一种合理的方法,并且您的安全规则的简化版本可能类似于:

service cloud.firestore {
  match /databases/{database}/documents {
    match /dms/{idPair}/messages/{msgId} {
      allow read, write: if 
        idPair.split('_')[0] == request.auth.uid ||
        idPair.split('_')[1] == request.auth.uid;
    }
  }
}

然后在您的 JS 代码中,您可以执行以下操作:

// generate idPair
function dmCollection(uid) {
  const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
  return firebase.firestore().collection('dms').doc(idPair).collection('messages');
}

// send a DM
function sendDM(toUid, messageText) {
  return dmCollection(toUid).add({
    from: firebase.auth().currentUser.uid,
    text: messageText,
    sent: firebase.firestore.FieldValue.serverTimestamp(),
  });
}

// retrieve DMs
function messagesWith(uid) {
  return dmCollection(uid).orderBy('sent', 'desc').get();
}

请注意,它idPair是通过加入一对已排序的 UID 来构建的,因此无论哪个用户发送它都将是稳定的。


推荐阅读