Как сделать запрос к существующим дочерним узлам одного и того же узла и обойти их, чтобы определить, существует ли он? - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь обновить (добавить) новых детей в базе данных Firebase. В этом сценарии я обновляю два узла и _ "door / {MACaddress_1} / ins" _ & _ "doors / {MACaddress_2} / ins" _, и оба этих узла должны записывать через функцию Google Cloud на одноуровневый узел с именем "номера / {roomPushKey} / INS" .

Я буду обновлять начальные узлы "doors" с помощью программы Arduino на устройстве IoT с уникальным MAC-адресом, который подключается к базе данных, к '/ doors /' + {MAC Address} + '/ ins'.

Вот основные условия:

1) Если "rooms / {roomPushKey} / ins" еще не создан, то создайте его (предотвращая сценарий неопределенной или нулевой ошибки при записи первых данных).

2) Обе "двери" обычно имеют разные дочерние ключи. Поэтому я не могу просто перезаписать данные одноуровневого узла "room" , потому что это приведет к удалению узлов одной двери, которая не обновлялась. Здесь я должен убедиться, что "rooms / {roomPushKey} / ins" получает только новые данные от каждой из дверей .

3) Мне нужно определить, не существует ли уже записанных новых данных на узле "rooms / {roomPushKey} / ins" , потому что иногда обе * doors * будут иметь тот же ключ, и когда это происходит, облачной функции необходимо добавить суффикс "_a" ко второму записываемому ключу.

Допустим, это моя исходная структура данных.

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 
      }
    }
  }

Я получил большую помощь от Рено Тарнека на прошлой неделе, но я не думаю, что сформулировал свой вопрос достаточно хорошо.

Итак, это текущее состояние функции Google Cloud:

// 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);
    });
});

Это клонирует все данные, которые уже присутствовали в базе данных (не самый последний новый ключ: пара). Пример, если добавить «ключ: пара» в виде «1999999999999: истина» в базу данных, подобную этой:

rooms: {
    -LBMH_8KHf_N9CvLqhzU: {
      ins: {

        1525104151100: true,
        1525104151183: true,
        1525104151220: true,
        1525104151440: true,
        1525104150000: true,
      }
    }
  }

Я получаю "rooms / {roomPushKey} / ins" , который выглядит следующим образом:

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
      }
    }
  }

Когда следует написать это:

  rooms: {
    -LBMH_8KHf_N9CvLqhzU: {
      ins: {

        1525104151100: true,
        1525104151183: true,
        1525104151220: true,
        1525104151440: true,
        1525104150000: true,
        1999999999999: true
      }
    }
  }

И затем, если другая дверь пишет «1999999999999: истина», она должна только добавить «_a» к этому последнему узлу:

  rooms: {
    -LBMH_8KHf_N9CvLqhzU: {
      ins: {

        1525104151100: true,
        1525104151183: true,
        1525104151220: true,
        1525104151440: true,
        1525104150000: true,
        1999999999999: true,
        1999999999999_a: true,

      }
    }
  }

Мне нужно клонировать последний «ключ: пара» , добавленный к «doors / {MACaddress} / ins» , если то последний "ключ: пара" уже находится в узле _ "rooms / {roomPushKey} / ins" _ и игнорирует все "ключ: пары", которые уже были в обеих "doors / {MACaddress} / ins " узлов.

Примерно так:

enter image description here

Есть мысли?

1 Ответ

0 голосов
/ 14 июня 2018

Этот вопрос возник из двух разных подходов. Пожалуйста, найдите их здесь:

1) Renaud Tarnec с использованием облачной функции

Это должно сработать, но я не проверял это. Вам может потребоваться проверить, является ли insBefore неопределенным, в дополнение к тестированию, оно является нулевым. Я позволю вам точно настроить его.

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;
    const updates = {};
    if (insBefore === null || insBefore === undefined ) {
        Object.keys(insAfter).forEach(key => {
           updates['/rooms/' + roomPushKey + '/ins/' + key] = true;
        });
    } else {
        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);
    });
});.catch(error => {
    console.log(error);
    //+ other error treatment if necessary

});

2) второй подход был более прямым

Я решил решить эту проблему в программе Arduino, потому что все двери имеют разные MAC-адреса. Я просто добавил MAC-адрес в конец отметки времени, и потому что ни одна дверь не зарегистрирует два входа одновременно, что и помогло. для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...