Следующие действия должны помочь:
exports.migrateVisits = functions.database.ref('/data/{key}/{nestedKey}')
.onWrite((change:any, context:any) => {
// Get a reference to the Firestore document of the changed user
const key = context.params.key;
const userDoc = admin
.firestore()
.collection('data/' + key + '/nestedKeys')
.doc(context.params.nestedKey);
// If this user has been deleted, delete in Firestore also
if (!change.after.exists()) {
return userDoc.delete();
}
// Get the user object with the new changes,
// as opposed to its value before the edit
let userData = change.after.val();
// Now update Firestore with that change
return userDoc.set(userData);
});
Вы должны использовать context.params
, чтобы получить значения path
.
ОБНОВЛЕНИЕ следуя нашим комментариям.
Главное, на что нужно обратить внимание, так это то, что теперь мы слушаем на уровне /data/{key}
, вы должны отличать данные, принадлежащие основному документу, от данных, принадлежащих дочерним элементам.,В приведенном ниже коде я предлагаю сделать это на основе имени данных (пол, дата, возраст, идентификатор ...).Если во время цикла вы встретите элемент данных с другим именем (например, с идентификатором, например -LYC-HHqDFgL9PovJiBr
), это означает, что это дочерний документ.
Еще один момент, на который следует обратить внимание, - это использование пакетной записи, см. https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes
Кроме того, я позволю вам взять на себя проверку, если документ удален на нет.Другим аспектом, который вам, возможно, придется адаптировать, является управление уже существующими детьми, в случае, если вы изменяете возраст, например, под узлом -LYC-HHqDFgL9PovJiBr
, потому что в этом случае триггер все равно произойдет на уровне /data/{key}
.
exports.migrateVisits = functions.database
.ref('/data/{key}')
.onWrite((change:any, context:any) => {
const key = context.params.key;
let userData = change.after.val();
const mainDocObj = {};
let batch = admin.firestore().batch();
Object.keys(userData).forEach(e => {
if (e === 'gender') { //here, add the other main keys, e.g. with ['gender', 'age', 'country', ....].includes(e)
mainDocObj[e] = userData[e];
} else {
//it needs to be added as a doc in the sub-collection
const subDocRef = admin
.firestore()
.collection('data/' + key + '/nestedKeys')
.doc(e);
batch.set(subDocRef, userData[e]);
}
});
//We first write the mainDoc
return admin
.firestore()
.collection('data')
.doc(key)
.set(mainDocObj)
.then(() => {
//We then write the children in one batch
return batch.commit();
});
});