I am trying to update (adding) new children on a firebase database. On this scenario I am updating two nodes and_"door/{MACaddress_1}/ins"_ & _"doors/{MACaddress_2}/ins"_ and both of this nodes need to write through a Google Cloud function to a sibling node called "rooms/{roomPushKey}/ins".
I will be updating the initial "doors" nodes through an Arduino program on a IoT device with a unique MAC Address that is connecting to the database to the '/doors/' + {MAC Address} + '/ins'.
These are the essential conditions:
1) If the "rooms/{roomPushKey}/ins" is not created yet, then create it (preventing an undefined or null error scenario when the first data is written).
2) Both "doors" normally have different child keys. So I can't simply overwrite the data of the sibling "room" node because that would delete the nodes of the one door that wasn't being updated. Here I need to make sure the "rooms/{roomPushKey}/ins" only gets the new data from each of the doors.
3) I need detect if that new data written doesn't exist already on the sibling "rooms/{roomPushKey}/ins" node because sometimes both *doors* will have the same key, and when that happens the cloud function needs to add a suffix "_a" to the second key being written.
Lets say this my initial data structure.
root: { doors: { 111111111111: { MACaddress: "111111111111", inRoom: "-LBMH_8KHf_N9CvLqhzU", // I will need this value for the clone's path ins: { // I am creating several "key: pair"s here, something like: 1525104151100: true, 1525104151183: true, 1525104150000: true // Trouble! this key is also on the other door } }, 222222222222: { MACaddress: "222222222222", inRoom: "-LBMH_8KHf_N9CvLqhzU", // I will need this value for the clone's path ins: { // I am creating several "key: pair"s here, something like: 1525104151220: true, 1525104151440: true, 1525104150000: true // Trouble! this key is also on the other door } } }, rooms: { -LBMH_8KHf_N9CvLqhzU: { ins: { // I want the function to clone the same data here: 1525104151100: true, 1525104151183: true, 1525104151220: true, 1525104151440: true, 1525104150000: true, // this key is on both doors 1525104150000_a: true, // so a suffix must be added } } } I got a lot of help from Renaud Tarnec last week but I don't think I phrased my question well enough.
So this is the current state of the Google Cloud function:
// UPDATING ROOMS INS/OUTS let insAfter; let roomPushKey ; exports.updateRoomIns = functions.database.ref('/doors/{MACaddress}').onWrite((change, context) => { const afterData = change.after.val(); // data after the write roomPushKey = afterData.inRoom; insAfter = afterData.ins; return admin.database().ref('/rooms/' + roomPushKey).once('value').then(snapshot => { const insBefore = snapshot.val().ins; // defining an object in the Rooms/{roomPushKey}/ins node to check what data is already there const updates = {}; // defining an empty updates object to populate depending on the scenario // avoiding the null/undefined error the first time data is written: all good here! if (insBefore === null || insBefore === undefined ) { Object.keys(insAfter).forEach(key => { updates['/rooms/' + roomPushKey + '/ins/' + key] = true; }); } else { // problem! Object.keys(insAfter).forEach(key => { if (insBefore.hasOwnProperty(key)) { updates['/rooms/' + roomPushKey + '/ins/' + key + '_a'] = true; } else { updates['/rooms/' + roomPushKey + '/ins/' + key] = true; } }); } return admin.database().ref().update(updates); }); }); This is cloning all the data that was already present in the database (not the most recent new key:pair). Example, if add a "key:pair" in such as "1999999999999: true" to a database like this:
rooms: { -LBMH_8KHf_N9CvLqhzU: { ins: { 1525104151100: true, 1525104151183: true, 1525104151220: true, 1525104151440: true, 1525104150000: true, } } } I am ending up with a "rooms/{roomPushKey}/ins" that looks like this:
rooms: { -LBMH_8KHf_N9CvLqhzU: { ins: { // I want the function to clone the same data here: 1525104151100: true, 1525104151183: true, 1525104151220: true, 1525104151440: true, 1525104150000: true, 1525104151100_a: true, 1525104151183_a: true, 1525104151220_a: true, 1525104151440_a: true, 1525104150000_a: true, 1999999999999: true // this last one isn't cloned but all the previous data in the database is } } } When it should write this:
rooms: { -LBMH_8KHf_N9CvLqhzU: { ins: { 1525104151100: true, 1525104151183: true, 1525104151220: true, 1525104151440: true, 1525104150000: true, 1999999999999: true } } } And then if the other door writes "1999999999999: true" it should only add the "_a" to the this last node:
rooms: { -LBMH_8KHf_N9CvLqhzU: { ins: { 1525104151100: true, 1525104151183: true, 1525104151220: true, 1525104151440: true, 1525104150000: true, 1999999999999: true, 1999999999999_a: true, } } } I need to clone the last "key:pair" added to the "doors/{MACaddress}/ins" if that last "key:pair" is already in the _"rooms/{roomPushKey}/ins"_ node, and neglect all the "key:pairs" that were already in both "doors/{MACaddress}/ins" nodes.
Something like this:
Any thoughts?
