Reputation: 2070
When I created my application I wrote code so that an empty user doc was created for each user that visited my app (using anonymous signed in state).
I'd like to delete all of the user documents from my firestore collection that have no data. This makes it easier for me to navigate to particular user docs & see how many users actually have data.
I've already modified the code in my app so that empty docs are no longer created, but I'd like to go back and get rid of all of the old empty ones.
What is the easiest way to do this?
Do I need to write a firebase function that performs this duty and trigger it manually?
I was hoping there would be a simpler way to perform this task, perhaps some kind of script I could run on the collection, but I haven't found anything thus far.
Upvotes: 1
Views: 492
Reputation: 2070
For anyone that would like to see the mechanics of a script that does this, I'm including the code and steps below:
You must get Service Account Credentials for you project. You can find more info on this here: https://firebase.google.com/docs/admin/setup
Copy & update the code for the script below.
run the script using node path/to/script.js
from your preferred console.
var admin = require("firebase-admin");
var serviceAccount = require("path/to/key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<PROJECT_ID>.firebaseio.com"
});
const firestore = admin.firestore();
const cleanDocs = async () => {
const documentRefs = await firestore.collection("users").listDocuments();
console.log(`got ${documentRefs.length} refs`);
const documentSnapshots = await firestore.getAll(...documentRefs);
console.log(`got ${documentSnapshots.length} snapshots`);
let deletePromises = [];
documentSnapshots.forEach((documentSnapshot, index) => {
if (documentSnapshot.exists) {
const data = documentSnapshot.data();
if (Object.keys(data).length == 0) {
// this user doc is empty
deletePromises.push(documentRefs[index].delete());
}
} else {
console.log(`Found missing document: ${documentSnapshot.id}`);
}
});
console.log(`deleting ${deletePromises.length} documents`);
// this next line doesn't seem to be necessary
await Promise.all(deletePromises);
return;
};
cleanDocs();
Upvotes: 1
Reputation: 317497
It might be kind of surprising, but documents without any fields cannot be queried, so there is no easy way of identifying only those documents. The way Firestore indexes work is based on the contents of field values. Without fields, there are no values to index, which means there is nothing to query.
What you will have to do instead is write code to get the entire contents of the collection, iterate each document, check it for lack of fields, then delete that document. You can do this on your desktop with the Firebase Admin SDK or some other Cloud SDK, no need to deploy to Cloud Functions.
Upvotes: 2