【问题标题】:How To Delete Firestore Collection From Android如何从 Android 中删除 Firestore 集合
【发布时间】:2018-09-03 01:16:53
【问题描述】:

问题

我正在寻找一种临时解决方案来从客户端删除集合以进行概念验证。我最终会按照建议将其重构到服务器上。

我正在添加删除特定 Firestore 用户的所有帐户信息的功能,包括他们在应用中保存的内容集合。根据Firestore documentation,客户端没有规定的方法可以这样做,因为建议在服务器上处理。

【问题讨论】:

    标签: android firebase google-cloud-firestore


    【解决方案1】:

    要从 Cloud Firestore 数据库中删除整个集合或子集合,您需要检索该集合或子集合中的所有文档并将其删除。

    如果您有较大的集合,您可能希望以较小的批次删除文档以避免内存不足错误。所以你应该重复这个过程,直到你删除了整个集合或子集合。

    即使 Firebase 团队不推荐删除操作,因为它具有负面的安全性和性能影响,您仍然可以执行此操作,但仅限于 small collections。如果您需要删除整个网络集合,请仅从受信任的服务器环境中执行此操作。

    对于 Kotlin,请使用以下函数:

    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
    }
    

    【讨论】:

    • 我正在使用 REST API 来操作我的收藏,因为我想为此构建一个 rust crate。 To delete an entire collection or subcollection from a Cloud Firestore database, you need to retrieve all the documents within the collection or subcollection and delete them. 这也适用于我的情况。谢谢。
    【解决方案2】:

    更新的解决方案

    Firebase 团队的 Delete Collections and Subcollections 记录解决方案更加可靠和安全,因为它是在客户端外部的云函数中实施的。我已经相应地重构了我的解决方案。

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

    旧解决方案(在客户端执行)

    传递给方法的是用户集合的引用和要处理的批量大小。

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

    【讨论】:

    • 如何在android中使用deleteUser函数?
    • 根据我在 2018 年的回忆,@PokhrajSah,根据文档,不建议这样做。
    猜你喜欢
    • 2021-08-27
    • 2019-02-06
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    相关资源
    最近更新 更多