Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Node script to upgrade GeoFirestore v3 (and older) docs to GeoFirestore v4
const admin = require("firebase-admin");
const { GeoFirestore, GeoCollectionReference } = require("geofirestore");
/**
* Generate new private key by selecting a project from below:
* https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk
*/
const SERVICE_ACCOUNT = require("./serviceAccountKey.json");
/**
* Set the collection to update here.
*/
const COLLECTION_NAME = "restaurants";
/**
* If you use a custom key, define it here, otherwise leave this.
*/
const CUSTOM_KEY = "coordinates";
admin.initializeApp({
credential: admin.credential.cert(SERVICE_ACCOUNT),
databaseURL: "https://" + SERVICE_ACCOUNT["project_id"] + ".firebaseio.com",
});
const firestore = admin.firestore();
const geofirestore = new GeoFirestore(firestore);
const collection = firestore.collection(COLLECTION_NAME);
const geocollection = new GeoCollectionReference(collection);
let totalUpdated = 0;
function updateCollection(query) {
return new Promise((resolve, reject) =>
deleteQueryBatch(query.limit(500), resolve, reject)
);
}
function deleteQueryBatch(query, resolve, reject) {
query
.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size === 0) {
console.log(`DONE, UPDATED ${totalUpdated}`);
return 0;
}
console.log(
`UPDATING ${snapshot.size} GEODOCUMENTS, ALREADY UPDATED ${totalUpdated}`
);
// Update documents in a batch
const batch = geofirestore.batch();
snapshot.docs.forEach((doc) => {
const geodoc = geocollection.doc(doc.id);
batch.set(geodoc, doc.data().d, { customKey: CUSTOM_KEY });
});
return batch.commit().then(() => snapshot.size);
})
.catch((e) => {
console.warn(
"This script was unable to convert your collection for GeoFirestore v4.",
e.details
);
return 0;
})
.then((numUpdated) => {
totalUpdated += numUpdated;
if (numUpdated === 0) {
resolve();
return;
}
process.nextTick(() => deleteQueryBatch(query, resolve, reject));
})
.catch((err) => reject(err));
}
(async () => {
await updateCollection(collection.orderBy("g").orderBy("l").orderBy("d"));
})();
@smolugu
Copy link

smolugu commented Sep 23, 2020

@MichaelSolati Thank you!

Also, I am getting empty results when I use where condition as below
const value = await query.where('notifications', '==', true).get();

I thought "notifications" field needs to be in all firestore documents of a collection. so updated all documents with "notifications" field but still the query returns empty set of documents.

Can you please let me know if it is possible to filter the query results using where clause?

Regards,
Shyam.

@cyrilblanchet
Copy link

cyrilblanchet commented Oct 25, 2020

I think you can delete the line #20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment