1

I´m creating this chat app using Firebase. I wanted to create a system where every device having the chat app installed is responsible for delivering chat messages.

Even if the device did not send the message it plays a part in the pool of workers, that deliver chat messages.

Now for a normal chat app the device that creates the chat message can easily send the message using E.g. OneSignal.

In my case user can chat with abstract things and there can be many people listening for new chat messages. One is sending and 1000+ is listening.

Here is where the problem comes. If one device is responsible for notifying 1000+ other it can get really heavy on the load. I was thinking all other devices can help out with the delivery,

so I´m trying this Firebase database notification entry:

{
  "NOTIFICATIONS" : {
    "-Kg4_cnR9T8Efx77rL2n" : {
      "targetId" : "-KfpVVenyQccKqAxxrvE",
      "text1" : "There´s a message for you",
      "text2" : "Pluto",
      "text3" : "",
      "time" : 1490447404504,
      "type" : "chatMessage"
    },
    "-Kg4_eWQFZndhztPqSTp" : {
      "targetId" : "-KfpWz7ZWBAa_8pLM7tI",
      "text1" : "There´s a message for you",
      "text2" : "Saturnus",
      "text3" : "",
      "time" : 1490447411536,
      "type" : "chatMessage"
    }
  }
}

and when one device is creating a message it post this new NOTIFICATIONS that will be picked up by all devices that are listening.

Now since all devices is listening on the NOTIFICATIONS and will grab one NOTIFICATIONS and send the chat message heads up, to all other devices that are registered on the targetId the problem obviously arise.

Here are the TARGET_VISITORS. This are the users that are registers for new chat messages.

 {
  "TARGET_VISITORS" : {
  "-KfpVVenyQccKqAxxrvE" : {
    "HnhLyXRxUINmlltK3jdsfxx2QBYiQ53" : {
      "notify" : true,
      "time" : 1490300590623,
      "userFirebaseId" : "HnhLyXRxUINmlltK3jdsfxx2QBYiQ53"
    }
  },
  "-KfpWz7ZWBAa_8pLM7tI" : {
    "HnhLrryXUINmlltK3jdsfxx2QBYi3455" : {
      "notify" : true,
      "time" : 1490300581677,
      "userFirebaseId" : "HnhLrryXUINmlltK3jdsfxx2QBYi3455"
    }
  } 

Can I use the Firebase Transaction for this?

Like one device pick up a NOTIFICATIONS and then gets maybe 10 TARGET_VISITORS (there can be 1000+), and in a Firebase transaction locking down TARGET_VISITORS to perform the chat message heads up delivery on his userFirebaseId or OneSignal PlayerId.?

After that the TARGET_VISITORS can save the NOTIFICATIONS id and by doing that prevent getting duplicate messages.

Maybe creating a visitor lock rule like:

  "TARGET_VISITORS_LOCK": {
          ".read": "auth != null",
          "$FirebaseId": {
                // This need to be a final entity.   
                // we can write as long as old data or new data does not exist.
                // In other words, we can write if we're deleting or creating data, but not updating data.
                ".write": "!data.exists() || !newData.exists() && auth != null"
          }    
    }, 

And then run an Data Fan Out updateChildren on the TARGET_VISITORS_LOCK, if it fails it means some other device is running the updateChildren before me and sending the notification to the single device. What will happen her if device having an offline period?

Many devices in the pool of workers can have the same NOTIFICATIONS to try to send and they will fight over TARGET_VISITORS, so to speak

Then comes the problem to know when to remove a NOTIFICATIONS entry, remove it when all TARGET_VISITORS have been notified :) Yea this is quite fun :)

It´s all theoretical at this point and i´m reading a loot so hoping for some input about this?

Tord Larsen
  • 2,670
  • 8
  • 33
  • 76
  • Hi Erik, did you explore firebase topics? Topics in some way models a one to many relation as you describes. – Juan Pablo Mar 27 '17 at 11:07
  • No I have not explore any topic describing this. Maybe because it´s advanced and must be customized. Not a main stream consumer approach. – Tord Larsen Mar 27 '17 at 11:27

0 Answers0