Firestore 使用 Firebase 函数删除帐户删除时的所有用户数据
Firestore delete all user data on account delete using a Firebase Function
我是 Firebase/Firestore 的新手,正在尝试创建一个 Firebase 函数,该函数将在删除 Auth 帐户时删除所有用户数据。
我的函数在删除帐户时成功调用,我正在尝试删除该用户的名为链接的集合,然后删除用户文档。但是我收到 linksRef.forEach is not a function.
的错误
关于如何执行此级联删除的任何指导?
exports.deleteUserData = functions.auth.user().onDelete((event) => {
const userId = event.data.uid;
const store = admin.firestore();
store.collection('users').doc(userId).get().then(user => {
if (user.exists) {
user.collection('links').get().then(links => {
links.forEach(link => {
link.delete();
})
return;
}).catch(reason => {
console.log(reason);
});
user.delete();
return;
}
else {
// User does not exist
return;
}
}
).catch(reason => {
console.log(reason);
});
});
根据@Doug Stevenson 关于 Promises 的评论,我设法通过拼凑代码来实现它。绝对不是最干净的,但如果有人试图做类似的事情,它会起作用。
// Delete user data when user deleted
exports.deleteUserData = functions.auth.user().onDelete((event) => {
const userId = event.data.uid;
const database = admin.firestore();
const linksRef = database.collection('users').doc(userId).collection('links');
const deleteLinks = deleteCollection(database, linksRef, BATCH_SIZE)
return Promise.all([deleteLinks]).then(() => {
return database.collection('users').doc(userId).delete();
});
});
/**
* Delete a collection, in batches of batchSize. Note that this does
* not recursively delete subcollections of documents in the collection
*/
function deleteCollection (db, collectionRef, batchSize) {
var query = collectionRef.orderBy('__name__').limit(batchSize)
return new Promise(function (resolve, reject) {
deleteQueryBatch(db, query, batchSize, resolve, reject)
})
}
function deleteQueryBatch (db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size === 0) {
return 0
}
// Delete documents in a batch
var batch = db.batch()
snapshot.docs.forEach(function (doc) {
batch.delete(doc.ref)
})
return batch.commit().then(function () {
return snapshot.size
})
}).then(function (numDeleted) {
if (numDeleted <= batchSize) {
resolve()
return
}
else {
// Recurse on the next process tick, to avoid
// exploding the stack.
return process.nextTick(function () {
deleteQueryBatch(db, query, batchSize, resolve, reject)
})
}
})
.catch(reject)
}
基于来自 Firebase 的this official doc,似乎很容易设置一个clearData
函数。
它只支持基本的 Firestore 结构。但在你的情况下,它应该只配置 user_privacy.json
类似的东西:
{
"firestore": {
"clearData": [
{"collection": "users", "doc": "UID_VARIABLE", "field": "links"},
{"collection": "users", "doc": "UID_VARIABLE"}
],
}
}
对于更复杂的情况,需要调整函数代码。
请参考the doc
我是 Firebase/Firestore 的新手,正在尝试创建一个 Firebase 函数,该函数将在删除 Auth 帐户时删除所有用户数据。
我的函数在删除帐户时成功调用,我正在尝试删除该用户的名为链接的集合,然后删除用户文档。但是我收到 linksRef.forEach is not a function.
的错误关于如何执行此级联删除的任何指导?
exports.deleteUserData = functions.auth.user().onDelete((event) => {
const userId = event.data.uid;
const store = admin.firestore();
store.collection('users').doc(userId).get().then(user => {
if (user.exists) {
user.collection('links').get().then(links => {
links.forEach(link => {
link.delete();
})
return;
}).catch(reason => {
console.log(reason);
});
user.delete();
return;
}
else {
// User does not exist
return;
}
}
).catch(reason => {
console.log(reason);
});
});
根据@Doug Stevenson 关于 Promises 的评论,我设法通过拼凑代码来实现它。绝对不是最干净的,但如果有人试图做类似的事情,它会起作用。
// Delete user data when user deleted
exports.deleteUserData = functions.auth.user().onDelete((event) => {
const userId = event.data.uid;
const database = admin.firestore();
const linksRef = database.collection('users').doc(userId).collection('links');
const deleteLinks = deleteCollection(database, linksRef, BATCH_SIZE)
return Promise.all([deleteLinks]).then(() => {
return database.collection('users').doc(userId).delete();
});
});
/**
* Delete a collection, in batches of batchSize. Note that this does
* not recursively delete subcollections of documents in the collection
*/
function deleteCollection (db, collectionRef, batchSize) {
var query = collectionRef.orderBy('__name__').limit(batchSize)
return new Promise(function (resolve, reject) {
deleteQueryBatch(db, query, batchSize, resolve, reject)
})
}
function deleteQueryBatch (db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size === 0) {
return 0
}
// Delete documents in a batch
var batch = db.batch()
snapshot.docs.forEach(function (doc) {
batch.delete(doc.ref)
})
return batch.commit().then(function () {
return snapshot.size
})
}).then(function (numDeleted) {
if (numDeleted <= batchSize) {
resolve()
return
}
else {
// Recurse on the next process tick, to avoid
// exploding the stack.
return process.nextTick(function () {
deleteQueryBatch(db, query, batchSize, resolve, reject)
})
}
})
.catch(reject)
}
基于来自 Firebase 的this official doc,似乎很容易设置一个clearData
函数。
它只支持基本的 Firestore 结构。但在你的情况下,它应该只配置 user_privacy.json
类似的东西:
{
"firestore": {
"clearData": [
{"collection": "users", "doc": "UID_VARIABLE", "field": "links"},
{"collection": "users", "doc": "UID_VARIABLE"}
],
}
}
对于更复杂的情况,需要调整函数代码。
请参考the doc