From 2724879c43a33ded2d15ee725e4820f1edd50b23 Mon Sep 17 00:00:00 2001 From: FRANCISCO JAVIER ALARCON ESPARZA Date: Sat, 7 Feb 2026 00:15:34 +0000 Subject: [PATCH] fix(firestore): use recursive delete for collection Update delete collection sample to use recursiveDelete Create test for this function Update previous uses of deleteCollection --- samples/snippets/pom.xml | 2 +- .../snippets/ManageDataSnippets.java | 28 ++++++------------- .../firestore/BaseIntegrationTest.java | 10 +++++++ .../snippets/ManageDataSnippetsIT.java | 24 ++++++++++++++-- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 4cae680215..31c964c5fc 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -34,7 +34,7 @@ com.google.cloud libraries-bom - 26.65.0 + 26.75.0 pom import diff --git a/samples/snippets/src/main/java/com/example/firestore/snippets/ManageDataSnippets.java b/samples/snippets/src/main/java/com/example/firestore/snippets/ManageDataSnippets.java index a5543f2532..f23ff7fc16 100644 --- a/samples/snippets/src/main/java/com/example/firestore/snippets/ManageDataSnippets.java +++ b/samples/snippets/src/main/java/com/example/firestore/snippets/ManageDataSnippets.java @@ -24,7 +24,6 @@ import com.google.cloud.firestore.FieldValue; import com.google.cloud.firestore.Firestore; import com.google.cloud.firestore.Query; -import com.google.cloud.firestore.QueryDocumentSnapshot; import com.google.cloud.firestore.QuerySnapshot; import com.google.cloud.firestore.SetOptions; import com.google.cloud.firestore.TransactionOptions; @@ -304,27 +303,16 @@ void deleteDocument() throws Exception { } // [START firestore_data_delete_collection] - /** - * Delete a collection in batches to avoid out-of-memory errors. Batch size may be tuned based on - * document size (atmost 1MB) and application requirements. - */ - void deleteCollection(CollectionReference collection, int batchSize) { + /** Delete a collection and all its subcollections. */ + void deleteCollection(CollectionReference collection) { + Firestore db = collection.getFirestore(); + + ApiFuture future = db.recursiveDelete(collection); try { - // retrieve a small batch of documents to avoid out-of-memory errors - ApiFuture future = collection.limit(batchSize).get(); - int deleted = 0; - // future.get() blocks on document retrieval - List documents = future.get().getDocuments(); - for (QueryDocumentSnapshot document : documents) { - document.getReference().delete(); - ++deleted; - } - if (deleted >= batchSize) { - // retrieve and delete another batch - deleteCollection(collection, batchSize); - } + future.get(); + System.out.println("Collection and all its subcollections deleted successfully."); } catch (Exception e) { - System.err.println("Error deleting collection : " + e.getMessage()); + System.err.println("Error deleting collection recursively : " + e.getMessage()); } } diff --git a/samples/snippets/src/test/java/com/example/firestore/BaseIntegrationTest.java b/samples/snippets/src/test/java/com/example/firestore/BaseIntegrationTest.java index 61017ebaa9..7e585475ff 100644 --- a/samples/snippets/src/test/java/com/example/firestore/BaseIntegrationTest.java +++ b/samples/snippets/src/test/java/com/example/firestore/BaseIntegrationTest.java @@ -83,6 +83,16 @@ protected static void deleteAllDocuments(Firestore db) throws Exception { } } + protected static void deleteCollection(Firestore db, String collectionName) throws Exception { + ApiFuture future = db.recursiveDelete(db.collection(collectionName)); + try { + future.get(); + System.out.println("Collection and all its subcollections deleted successfully."); + } catch (Exception e) { + System.err.println("Error deleting collection recursively : " + e.getMessage()); + } + } + @AfterClass public static void tearDownAfterClass() throws Exception { db.close(); diff --git a/samples/snippets/src/test/java/com/example/firestore/snippets/ManageDataSnippetsIT.java b/samples/snippets/src/test/java/com/example/firestore/snippets/ManageDataSnippetsIT.java index b13c19e2d3..fcb602d252 100644 --- a/samples/snippets/src/test/java/com/example/firestore/snippets/ManageDataSnippetsIT.java +++ b/samples/snippets/src/test/java/com/example/firestore/snippets/ManageDataSnippetsIT.java @@ -26,6 +26,9 @@ import com.google.cloud.firestore.CollectionReference; import com.google.cloud.firestore.DocumentReference; import com.google.cloud.firestore.DocumentSnapshot; +import com.google.cloud.firestore.QuerySnapshot; +import com.google.cloud.firestore.WriteResult; + import java.util.Date; import java.util.Map; import java.util.Objects; @@ -152,6 +155,23 @@ public void testDeleteDocument() throws Exception { getDocumentDataAsMap(db.collection("cities").document("DC")); } + @Test + public void testDeleteCollection() throws Exception { + // Create collection and document to be deleted + Map docData = Map.of("name", "Los Angeles"); + ApiFuture future = db.collection("usa-cities").document("LA").set(docData); + future.get(); + + // Delete collection + manageDataSnippets.deleteCollection(db.collection("usa-cities")); + + // Verify collection is deleted by trying to read from it + CollectionReference collectionReference = db.collection("usa-cities"); + collectionReference.limit(1); + QuerySnapshot snapshot = collectionReference.get().get(); + assertTrue(snapshot.isEmpty()); + } + @Test public void testSimpleTransaction() throws Exception { DocumentReference docRef = db.collection("cities").document("SF"); @@ -208,8 +228,8 @@ public void testSnapshotReads() throws Exception { @AfterClass public static void tearDown() throws Exception { - manageDataSnippets.deleteCollection(db.collection("cities"), 10); - manageDataSnippets.deleteCollection(db.collection("users"), 10); + deleteCollection(db, "cities"); + deleteCollection(db, "users"); manageDataSnippets.close(); } }