Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to listen to nested changes using Firebase?

Background:

I'm trying to send SMS messages via the browser using Firebase, Twilio, and Node.js. My current data structure in Firebase looks like this:

{ messages :
  { +15553485 :
    { FB-GENERATED-KEY-1 :
      { body: "hello world"
        timestamp: 1461758765472 }
    },
    { FB-GENERATED-KEY-3 :
      { body: "I love dogs"
        timestamp: 1461758765475 }
      }
    }
  },
  { +15550000 :
    { FB-GENERATED-KEY-2 :
      { body: "goodbye world"
        timestamp: 1461758765473 }
    },
    { FB-GENERATED-KEY-4 :
      { body: "I love cats"
        timestamp: 1461758765476 }
      }
    }
  }
}

When a message is added to Firebase via the frontend the backend needs to get notified in order to send an SMS via Twilio. When the backend gets a reply from the phone (via Twilio), it adds it to Firebase.

Problems:

When I listen for changes to a thread I receive all messages sent/recieved for that phone number. Obviously the backend doesn't want to send all the messages again, so I'm only interested in the most recent message added to the thread.

Also I can't seem to easily get the phone number (the key) that has messages underneath it.

What I've tried:

ref.child('messages').on('child_added', ...) — this works for new phone numbers that are added at /messages, however Firebase doesn't send through the new phone number (key), only everything from FB-GENERATED-KEY-2 down.

ref.child('messages').on('child_changed', ...) — this returns all of the messages in a thread, not only the new ones. I can sort on the server and find the most recent message, but that seems like it'll get heavy quite quickly – what if you've sent thousands of messages?

Storing messages at the root level (aka. flattening the tree) and storing the number as an attribute instead could work, but I'm going to need to use the phone number as a sort of index to connect with other data later (like a foreign key).

Questions:

  • How can I only get the most recent message when listening to activity on the parent /messages and not a particular phone number?
  • How can I get the key (phone number) when using a child_ event?
  • Does this data structure make sense?
like image 246
Benjamin Humphrey Avatar asked Oct 18 '22 10:10

Benjamin Humphrey


1 Answers

You can get the Firebase key by calling key() on the snapshot returned by your child_added listener.

Then you can add another nested listener like this:

ref.child('messages').on('child_added', function (snapshot) {
    var phone = snapshot.key();
    ref.child('messages').child(phone).on('child_added', function (message) {
        //send SMS
    }, function (error) {

    });
}, function (error) {

});
like image 79
kolli Avatar answered Nov 15 '22 05:11

kolli