问题
我正在寻找一种临时解决方案,用于在我的概念验证中从客户端删除集合。我最终会按照建议将其重构到服务器端。
我正在添加一个函数,用于删除特定Firestore用户的所有帐户信息,包括应用程序中保存的内容集合。根据Firestore文档,没有建议从客户端处理此操作,因为推荐在服务器上处理。
我正在寻找一种临时解决方案,用于在我的概念验证中从客户端删除集合。我最终会按照建议将其重构到服务器端。
我正在添加一个函数,用于删除特定Firestore用户的所有帐户信息,包括应用程序中保存的内容集合。根据Firestore文档,没有建议从客户端处理此操作,因为推荐在服务器上处理。
private fun deleteCollection(collection: CollectionReference, executor: Executor) {
Tasks.call(executor) {
val batchSize = 10
var query = collection.orderBy(FieldPath.documentId()).limit(batchSize.toLong())
var deleted = deleteQueryBatch(query)
while (deleted.size >= batchSize) {
val last = deleted[deleted.size - 1]
query = collection.orderBy(FieldPath.documentId()).startAfter(last.id).limit(batchSize.toLong())
deleted = deleteQueryBatch(query)
}
null
}
}
@WorkerThread
@Throws(Exception::class)
private fun deleteQueryBatch(query: Query): List<DocumentSnapshot> {
val querySnapshot = Tasks.await(query.get())
val batch = query.firestore.batch()
for (snapshot in querySnapshot) {
batch.delete(snapshot.reference)
}
Tasks.await(batch.commit())
return querySnapshot.documents
}
Firebase团队的删除集合和子集合文档中提供的解决方案更加可靠和安全,因为它在客户端之外的云函数中实现。我已相应地重构了我的解决方案。
/**
* Initiate a recursive delete of documents at a given path.
*
* This delete is NOT an atomic operation and it's possible
* that it may fail after only deleting some documents.
*
* @param {string} data.path the document or collection path to delete.
*/
exports.deleteUser = () => functions.runWith({timeoutSeconds: 540, memory: '2GB'})
.https.onCall((data, context) => {
if (context.auth.uid !== data.userId)
throw new functions.https.HttpsError(
'permission-denied','Must be an administrative user to initiate delete.');
const path = data.path;
console.log(`User ${context.auth.uid} has requested to delete path ${path}`);
return firebase_tools.firestore.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
}).then(() => { return { path: path }; });
});
将用户Collection的引用和要处理的批量大小传递给该方法。
fun deleteCollection(collection: CollectionReference, batchSize: Int) {
try {
// Retrieve a small batch of documents to avoid out-of-memory errors/
var deleted = 0
collection
.limit(batchSize.toLong())
.get()
.addOnCompleteListener {
for (document in it.result.documents) {
document.getReference().delete()
++deleted
}
if (deleted >= batchSize) {
// retrieve and delete another batch
deleteCollection(collection, batchSize)
}
}
} catch (e: Exception) {
System.err.println("Error deleting collection : " + e.message)
}
}
Query query = firestore.collection("add_to_cart");
query.addSnapshotListener((snapshots, error) -> {
if (error != null) {
// Handle error
Log.e("ABCD", error.getMessage());
} else {
// Iterate over the documents
for (QueryDocumentSnapshot document : snapshots) {
// Do something with the document data
Log.e("ABCD -->", document.getId());
firestore.collection("add_to_cart").document(document.getId()).delete().addOnSuccessListener(aVoid -> {
// The snapshot was deleted successfully
Toast.makeText(CheckOutActivity.this, "Order placed successfully", Toast.LENGTH_SHORT).show();
}).addOnFailureListener(e -> {
// The snapshot could not be deleted
Log.e("TAG", "Error deleting snapshot -->" + e.getLocalizedMessage());
});
}
}
});
要从Cloud Firestore数据库中删除整个集合或子集合,您需要检索集合或子集合中的所有文档并将它们删除。
这也适用于我的情况。谢谢。 - Victor Oliveira