How Delete firebase collection document and with that delete all the sub collections and remove from authentications also using flutter?

huangapple go评论65阅读模式
英文:

How Delete firebase collection document and with that delete all the sub collections and remove from authentications also using flutter?

问题

我尝试删除Firebase集合文档以及删除所有子集合并从身份验证中删除用户,使用Flutter。这是我的数据库截图:

[![在此输入图像描述][1]][1]

我想要删除用户文档以及这些子集合(books和pdfs)。

我的代码:

void deleteUserDocument() async {
final sp = context.watch();
try {
// 获取当前用户的ID
final user = FirebaseAuth.instance.currentUser;
final uid = user?.uid;
if (uid != null) {
// 获取Firestore中用户文档的引用
final docRef = FirebaseFirestore.instance.collection("users").doc(uid);
// 删除用户文档中的所有子集合
final collections = await FirebaseFirestore.instance.collection("users").doc(uid).listCollections();
final batch = FirebaseFirestore.instance.batch();
for (final collectionRef in collections) {
final querySnapshot = await collectionRef.get();
for (final docSnapshot in querySnapshot.docs) {
batch.delete(docSnapshot.reference);
}
batch.delete(collectionRef);
}
await batch.commit();
// 删除用户文档
await docRef.delete();
// 从Firebase身份验证中删除用户
await user?.delete();
// 注销用户并导航到登录界面
sp.userSignOut();
nextScreenReplace(context, const LoginScreen());
}
} catch (e) {
// 处理删除过程中发生的任何错误
print('删除用户文档时出错:$e');
// 向用户显示错误消息
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('删除帐户失败')),
);
}
}


但是在这一行上显示错误:`final collections = await FirebaseFirestore.instance.collection("users").doc(uid).listCollections();`。

**错误截图:**

[![在此输入图像描述][2]][2]

如何解决这个错误?
[1]: https://i.stack.imgur.com/8YPyf.png
[2]: https://i.stack.imgur.com/bOTj8.png
英文:

I tried to delete firebase collection document and with that delete all the sub collections and remove from authentications also using flutter. here it is my database screenshot

How Delete firebase collection document and with that delete all the sub collections and remove from authentications also using flutter?

I want delete user document with those subcollection (books and pdfs).

my code

  void deleteUserDocument() async {
    final sp = context.watch<SignInProvider>();
    try {
      // Get the current user's ID
      final user = FirebaseAuth.instance.currentUser;
      final uid = user?.uid;
      if (uid != null) {
        // Get a reference to the user's document in Firestore
        final docRef = FirebaseFirestore.instance.collection("users").doc(uid);
        // Delete all subcollections in the user's document
        final collections = await FirebaseFirestore.instance.collection("users").doc(uid).listCollections();
        final batch = FirebaseFirestore.instance.batch();
        for (final collectionRef in collections) {
          final querySnapshot = await collectionRef.get();
          for (final docSnapshot in querySnapshot.docs) {
            batch.delete(docSnapshot.reference);
          }
          batch.delete(collectionRef);
        }
        await batch.commit();
        // Delete the user's document
        await docRef.delete();
        // Remove the user from Firebase Authentication
        await user?.delete();
        // Log the user out and navigate to the login screen
        sp.userSignOut();
        nextScreenReplace(context, const LoginScreen());
      }
    } catch (e) {
      // Handle any errors that occur during the deletion process
      print('Error deleting user document: $e');
      // Display an error message to the user
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Failed to delete account')),
      );
    }
  }

but in there show error on ** final collections = await FirebaseFirestore.instance.collection("users").doc(uid).listCollections();**

error screenshot

How Delete firebase collection document and with that delete all the sub collections and remove from authentications also using flutter?

how to solve this error ?

答案1

得分: 2

根据Firebase文档
>警告:删除文档不会删除其子集合!

以及

不建议从客户端删除集合。

相反,您应该删除具有子集合的文档,使用使用可调用云函数删除数据,然后从您的客户端应用程序调用它。

Firebase文档还提供了一个示例Firebase函数,用于删除文档,您可以在这里查看:解决方案:使用可调用云函数删除数据

英文:

According to Delete documents Firebase Docs
>Warning: Deleting a document does not delete its subcollections!

And

Deleting collections from the client is not recommended.

Instead you should delete the document which have subcollections with Delete data with a Callable Cloud Function and call it from your client Application.

Firebase Docs has also provided a sample firebase function to delete the document which you can check here : Solution: Delete data with a callable Cloud Function

答案2

得分: 1

这似乎有两个问题需要解决。

  • 第一个问题,正如Rohit Kharche之前指出的,删除用户文档不会自动删除其子集合。因此,您需要遍历每个子集合的文档以删除它们。
  • 第二个问题与Firebase批处理有关,它有500个文档的限制。如果子集合中的文档超过500个,批处理操作将失败,删除过程将无法完成。

下面的代码解决了所有这些问题:

void deleteUser() async {
  final sp = context.watch<SignInProvider>();

  /* 由于我们使用批处理来删除文档,通常批处理的最大大小
  * 为500个文档。
  */
  const int maxBatchSize = 500;

  // 定义用户集合;
  final List<String> collections = [
    "books",
    "pdfs",
  ];

  try {
    // 获取当前用户的ID
    final String? uid = FirebaseAuth.instance.currentUser?.uid;

    //循环遍历集合,并从用户删除每个集合项
    for (String collection in collections) {
      // 获取集合的快照。
      final QuerySnapshot snapshot = await FirebaseFirestore.instance
          .collection('Users')
          .doc(uid)
          .collection(collection)
          .get();
      // 获取文档列表;
      final List<DocumentSnapshot> querySnapshotList = snapshot.docs;

      // 获取列表长度(集合中的文档数)
      final int documentLengths = querySnapshotList.length;

      /* 下面的代码允许我们循环遍历文档并在每500个文档后删除它们,因为批处理在500个时满了。
       */
      final int loopLength = (documentLengths / maxBatchSize).ceil();
      for (int _ = 0; _ < loopLength; _++) {
        final int endRange = (querySnapshotList.length >= maxBatchSize)
            ? maxBatchSize
            : querySnapshotList.length;
        // 定义批处理实例
        final WriteBatch batch = FirebaseFirestore.instance.batch();
        for (DocumentSnapshot doc in querySnapshotList.getRange(0, endRange)) {
          batch.delete(doc.reference);
        }
        // 提交删除批处理
        batch.commit();
        querySnapshotList.removeRange(0, endRange);
      }
    }
    // 删除用户配置文件
    await FirebaseFirestore.instance.collection('Users').doc(uid).delete();

    // 从所有平台注销用户。
    sp.userSignOut();
    /*
    // 从所有平台注销用户。
    Future.wait([
      _googleSignIn.signOut(),
      _facebookAuth.logOut(),
      _firebaseAuth.signOut(),
    ]);
     */
  } catch (e) {
    // 处理删除过程中发生的任何错误
    print('删除用户文档时出错: $e');
    // 向用户显示错误消息
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('删除帐户失败')),
    );
  }
}
英文:

it seems that there are two issues that you need to address.

  • The first one, as pointed out by Rohit Kharche earlier, is that
    removing the user document does not automatically remove its
    subcollections. Therefore, you need to iterate through each
    subcollection's documents to delete them.
  • The second issue is related
    to Firebase batch, which has a limit of 500 documents. In case the
    subcollection has more than 500 documents, the batch operation will
    fail and the deletion process won't be completed.

The below code solution addresses all these issues:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

void deleteUser() async {
final sp = context.watch&lt;SignInProvider&gt;();
/* Since we are using batch to delete the documents usually the max batch size
* is 500 documents.
*/
const int maxBatchSize = 500;
// Define the users collections;
final List&lt;String&gt; collections = [
&quot;books&quot;,
&quot;pdfs&quot;,
];
try {
// Get the current user&#39;s ID
final String? uid = FirebaseAuth.instance.currentUser?.uid;
//loop through collection and delete each collection item from a user
for (String collection in collections) {
// Get the snapshot of a collection.
final QuerySnapshot snapshot = await FirebaseFirestore.instance
.collection(&#39;Users&#39;)
.doc(uid)
.collection(collection)
.get();
// Get the list of documents;
final List&lt;DocumentSnapshot&gt; querySnapshotList = snapshot.docs;
// Get the length of the list(no of documents in the collections)
final int documentLengths = querySnapshotList.length;
/* The below code allows us too loop through the documents and delete
them after every 500 documents, since batch is full at 500.
*/
final int loopLength = (documentLengths / maxBatchSize).ceil();
for (int _ = 0; _ &lt; loopLength; _++) {
final int endRange = (querySnapshotList.length &gt;= maxBatchSize)
? maxBatchSize
: querySnapshotList.length;
// Define the batch instance
final WriteBatch batch = FirebaseFirestore.instance.batch();
for (DocumentSnapshot doc in querySnapshotList.getRange(0, endRange)) {
batch.delete(doc.reference);
}
// Commit the delete batch
batch.commit();
querySnapshotList.removeRange(0, endRange);
}
}
// Delete the user profile
await FirebaseFirestore.instance.collection(&#39;Users&#39;).doc(uid).delete();
// Log out user from all platforms.
sp.userSignOut();
/*
// Log out user from all platforms.
Future.wait([
_googleSignIn.signOut(),
_facebookAuth.logOut(),
_firebaseAuth.signOut(),
]);
*/
} catch (e) {
// Handle any errors that occur during the deletion process
print(&#39;Error deleting user document: $e&#39;);
// Display an error message to the user
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(&#39;Failed to delete account&#39;)),
);
}
}

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月11日 14:25:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982957.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定