使用 Firestore 显示徽章通知

时间:2021-02-16 02:08:16

标签: javascript firebase vue.js google-cloud-firestore

您好,我正在使用 Firestore 创建一个聊天应用。我看到了很多关于使用云消息创建徽章通知的信息,但没有看到很多关于创建没有云消息的徽章通知的信息。有谁知道如何做到这一点?当用户收到他们尚未阅读的消息时,我试图在图标上显示一个点。如果我也能知道他们没有阅读的消息总数就更好了。

Firestore 结构

 users
      |
      ---- chatList (subcollection)
              ---- chatFrom: user1_Id
              ---- chatWith: user2_Id
              ---- chatRoomId: smallerUserID_biggerUserID
chatRooms
      |
      ---- smallerUserID_biggerUserID (subcollection)
              ---- content: "Hello"
              ---- id: 1613422354427
              ---- idFrom: user1_Id
              ---- timestamp: 1613422354427
                    

在聊天室集合中获取和发送消息

getMessages() {
  this.listMessage = []; 
  
  db.collection('chatRooms').doc(this.chatRoomId).collection(this.chatRoomId)
    .onSnapshot((snapshot) => {
      snapshot.docChanges().forEach((change) => {
        if (change.type === 'added') {
          this.listMessage.push(change.doc.data());
        }
     });
  });
},

async sendMessage(content) {
  if (content.trim() === '') { return }
  
  const timestamp = moment().valueOf().toString();
  const idFrom = this.authUser.userId;
  const idTo = this.currentPeerUser.userId;
  const message = { id: timestamp, idFrom, idTo, timestamp, content };

  const chatRoomRef = db.collection('chatRooms').doc(this.chatRoomId)
                        .collection(this.chatRoomId).doc(timestamp);
  await chatRoomRef.set(message);

  this.inputValue = '';
},

1 个答案:

答案 0 :(得分:1)

正如@John 所提到的,更好的选择是在您的对象中添加一个额外的字段,告诉您消息是否已被阅读,并且可以通过对您进行一些简单的更改来完成getMessages() :

getMessages() {
  this.listMessage = []; 
  
  db.collection('chatRooms').doc(this.chatRoomId).collection(this.chatRoomId)
    .onSnapshot((snapshot) => {
      snapshot.docChanges().forEach((change) => {
        if (change.type === 'added') {
          this.listMessage.push({
              isNew: true,
              message: change.doc.data()
          });
        }
     });
  });
}

您可以使用 isNew 来显示或不显示 newMessage 图标并在阅读消息时更改其值,您可以通过将以下内容添加到代码中来使用 Intersection Observer

//options to your observer
let options = {
  root: document.querySelector('#YOUR_ROOT_ELEMENT_HERE'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

let target = document.querySelector('#YOUR_TARGET_ELEMENT_HERE');
observer.observe(target);

let callback = (entries, observer) => {
    this.listMessage.forEach(function(messageItem) {
        messageItem.isNew = false;
    });
};

在这个例子中,YOUR_ROOT_ELEMENT_HERE 将是你元素的父元素,我假设在这种情况下它可能是一个 Scroll 而 YOUR_TARGET_ELEMENT_HERE 将是未读消息。当交叉点发生时,所有消息都将被标记为已读,但您可以根据需要完善该逻辑。