删除Firestore集合中的所有文档

时间:2020-05-22 06:56:20

标签: android google-cloud-firestore

我制作了一个按钮,该按钮应该允许用户根据其用户ID删除所有数据,该按钮具有与“删除您的帐户”按钮相同的目的,但是不起作用。我尝试使用以下代码删除集合中的所有文档:

final String userid = FirebaseAuth.getInstance.getCurrentUser().getUid();

        db.collection("main").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult()){
                    db.collection("main").document(userid).delete();
                }
            }
        })

有一个runtimeExecution:没有权限错误

    com.google.android.gms.tasks.RuntimeExecutionException: com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.

我将安全规则设置如下,以便其他用户无法访问其他用户的数据。

service cloud.firestore {
  match /databases/{database}/documents {
    match /main/{userId}/{document=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

不确定该怎么办,我认为安全规则可以防止安全问题,但是我认为这会导致此权限错误?

先谢谢您。

4 个答案:

答案 0 :(得分:1)

此查询正尝试获取名为“ main”的集合中的所有所有文档:

db.collection("main").get()

您的安全规则不允许这样做。这些规则仅允许用户在main中读写自己的文档。

不清楚您要删除的内容是什么,但是如果只是main下的用户文档,则根本不需要查询。只需这样做:

db.collection("main").document(userid).delete();

答案 1 :(得分:1)

如果要访问主集合下的所有文档,则应将Firebase规则更改为

service cloud.firestore {
    match /databases/{database}/documents {
      match /{document=**} {
       allow read, write: if true;
    }
  }
}

尽管如果您只想删除在此处的代码中正在执行的单个用户数据:-

db.collection("main").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult()){
                db.collection("main").document(userid).delete();
            }
        }
    })

您不应该纠正整个查询,而只需使用

删除用户文档即可。
db.collection("main").document(userid).delete();

答案 2 :(得分:0)

没有API可以一次性删除整个集合(或其内容)。

从Firestore文档中: https://firebase.google.com/docs/firestore/manage-data/delete-data

”要在Cloud Firestore中删除整个集合或子集合,请检索集合或子集合中的所有文档并将其删除。如果您有更大的集合,则可能希望以较小的批次删除这些文档,以避免超出范围。内存错误。重复此过程,直到您删除了整个集合或子集合。”

答案 3 :(得分:0)

更新:

经过研究并在此站点上阅读了有关此问题的许多其他答案之后,我使用了这种方法,我认为对于像我这样的假人来说这是如此简单,但我从未在其他答案中提及我不确定原因:

要完全从身份验证中删除用户,我使用了名为“删除用户数据”的Firestore扩展,这是一个很大的帮助,这很神奇,它使我可以通过使用以下代码来删除用户:

FirebaseAuth.getInstance().getCurrentUser().delete().addOnSuccessListener(new OnSuccessListener<Void>() {...}

它不仅删除用户身份验证,而且仅删除该代码,firestore中特定用户的数据以及存储中的图像也消失了。太棒了! 重要的一点是,您必须从身份验证连接用户UID,并将UID连接到Firestore和存储。

要了解有关如何使用“删除用户数据” Firestore扩展的更多信息(它仍处于beta模式),请尝试查看JORGE VERGARA的这篇出色的博客教程:Installing the Delete User Data extension

如何设置扩展名的配置以删除用户: enter image description here

如何使用扩展名:它非常简单,我很高兴能帮助我如此轻松地删除用户而不必大惊小怪 enter image description here

这是存储结构: enter image description here

我的Firestore的结构:

main(collection)--->userID---->journal(collection)----->journalIDdsvsfbsf
                                                  ----->journalIDdfvdbgnd
                --->userID2--->journal(collection)----->journalIDdsvsfbsf
                                                  ----->journalIDdfvdbgnd

enter image description here

身份验证结构: enter image description here

查看Firestore和存储必须如何与同一用户UID连接,以便Firestore扩展可以通过删除身份验证轻松删除用户。

如果您仍然想使用旧方法: 我注意到,仅使用delete方法就无法删除包含一个或多个子集合的firestore文档。例如,如果您要删除包含3个子集合的文档,则要删除该文档(在我的情况下为用户),则必须将所有文档归入一个子集合,然后将其全部删除,然后继续对该文档中的所有其他子集合执行相同的操作。一旦删除了文档中的所有子集合,包含它们的文档将自行消失。看起来Firestore就是这样工作的。

将其放入代码中: 删除包含子集合“ journal”的文档 在不使用扩展程序的情况下,我必须这样做:

FirebaseFirestore.getInstance().collection("main").document(userid).collection("journal").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (final QueryDocumentSnapshot document : task.getResult()) {
                            if (document.exists()){
                                db.collection("main").document(userid).collection("journal").document(document.getId()).delete().addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {

                                    }
                                }).addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        Toast.makeText(SettingsActivity.this, "Journal: " + e.getMessage(), Toast.LENGTH_LONG).show();
                                    }
                                });
                            } else {
                                Toast.makeText(SettingsActivity.this, "No data in JOURNAL", Toast.LENGTH_SHORT).show();
                            }
                        }
                    } else {
                        Toast.makeText(SettingsActivity.this, "Journal task: " + task.getException(), Toast.LENGTH_LONG).show();
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(SettingsActivity.this, "Error getting all the documents: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }
            });

如果该特定文档中有多个子集合,则要删除该子集合,必须针对不同的子集合多次重复该代码,这会使代码变得很长。

我希望这对试图从Firestore中删除用户的人有所帮助。 :)已经使用了扩展名。