Ziyaddin Sadygly
Ziyaddin Sadygly

Reputation: 9636

Atomically push new chat message and update lastMessage value on Firebase Realtime Database

I store chat messages and chat metadata in this structure:

project
|
-- chats
   |
   -- 1
      |
      -- -MFBvnTIQgVKdyFzDMpy
         |
         -- message: "hello"
      |
      -- -MEZutiaxOthE-7nDOkA
         |
         -- message: "how are you?"
   |
   -- 2
      |
      -- -MENuu8TjwWrBTkIzue_
         |
         -- message: "hi"
      |
      -- -MFBTqEqhR9Dtv3MlMd6
         |
         -- message: "you good?"
|
-- chatMetadata
   |
   -- 1
      |
      -- lastMessage: "how are you?"
   |
   -- 2
      |
      -- lastMessage: "you good?"

Whenever user submits a new chat message to a specific chat, that chat's lastMessage property should be updated inside chatMetadata. The process contains two separate operations: .push() for pushing new chat message and .update() for updating lastMessage property. How can I guarantee that lastMessage is always equal to last pushed chat message, if multiple users can submit messages to a specific chat simultaneously?

Upvotes: 0

Views: 203

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50830

You would have to use Realtime Database Triggers for Cloud Functions to do so.

// Listens for new messages added to /chats/:chatId/ and creates an
// uppercase version of the message to /chatMetadata/:chatId/

exports.updateLastMessage = functions.database.ref('/chats/{chatId}/')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      
      // You must return a Promise when performing asynchronous tasks inside a Functions 
      // Writing the lastMessage node 
      return snapshot.ref.parent.parent.child('chatMetadata').child(context.params.chatId).set({lastMessage: original.message});
});

Upvotes: 1

Related Questions