Export Firestore in JSON without Blaze plan - firebase

I have hundreds of entries in my firebase database and I'd like to try moving to SQL in case my Firebase free plan ever goes out of limit. Is there any way I can export the data in JSON format without buying the Blaze plan? (as my card doesn't work when I try to do payment)

I use firefoo... there is trial version for 14 days

To backup my collection manually I did this:
In the same project, created a file called backup.js that is called when I press a backup button.
In the backup.js endpoint, I fetch the collection and store every entry in the database, then I return this array of documents I just saved.
I console.log the returned data and in Browser's console, I right click the array output and click 'Copy Object' and save it in a text file.
backup.js (Next.js API Endpoint):
import { collection, doc, getDoc, getDocs } from "firebase/firestore";
import { StatusCodes } from "http-status-codes";
import { db } from "../../utils/firebase";
export default async function handler(req, res) {
const collectionName = "myCollection"
try {
// check firebase if slug exists
const documentSnapshot = await getDocs(collection(db, collectionName));
let backup = [];
documentSnapshot.forEach((doc) => {
backup.push(doc.data());
});
console.log(backup);
return res.status(StatusCodes.OK).send(backup);
} catch (err) {
console.log("Database Error", err);
}
}

Related

Modular Firebase Admin Database

Is there or will there be modular Firebase Admin Database functions i.e. update(), get(), set(), ref() etc.? Maybe there is a workaround?
Else I would have to code equal functions twice, like "craftBuilding()" on server (admin) and one for client.
Tried to:
import { getDatabase, ref, set, update, child, onChildAdded } from 'firebase-admin/database';
Error:
The requested module 'firebase-admin/database' does not provide an export named 'ref'
I expected to be able to use firebase rtdb functions like on client-side, to not code identical functions twice.
The Admin SDK is not totally modular yet but has some function such a getDatabase() starting V10.
import { getDatabase } from 'firebase-admin/database';
// TODO: Initialize Admin SDK
const db = getDatabase();
// usage
const ref = db.ref('../../..')
I would recommend using latest version of the SDK along with the existing syntax but use newer modular imports.
Since Firebase Admin is namespaced, ref is available after you initialize.
import { ref, update, set } from '#path/yourAdminFunctions';
var admin = require("firebase-admin");
// Initialize Admin SDK
var db = admin.database();
export db;
const dbReference = ref("your reference here");
const IDSnapFromQuery = query(dbReference, ["ID", "==", 10]);
You could modularize it yourself by creating functions for the operations you require in a separate file:
import { db } from '#path/yourMainFile';
export function ref(databaseReference) {
return db.ref(databaseReference);
};
// for query pass in the db.ref instance you're using
export function query(dbReference, queryParams) {
// identify what query params are e.g. ID == 10 in this example
// note that you will have to code the queryParams filter, I have left it out
dbReference
.orderByChild('ID')
.equalTo(10).on('child_added',
(snapshot) => {
return snapshot;
});
}
// do the same for update, set etc
You can read more on the admin SDK documentation.

React Query and using queryClient in both _app.js AND getInitialProps

So, in the docs, we have this code:
https://react-query.tanstack.com/guides/ssr#using-hydration
RE: The use of 'useRef' to store a reference.
// _app.jsx
import { QueryClient, QueryClientProvider } from 'react-query'
import { Hydrate } from 'react-query/hydration'
export default function MyApp({ Component, pageProps }) {
const queryClientRef = React.useRef()
if (!queryClientRef.current) {
queryClientRef.current = new QueryClient()
}
return (
<QueryClientProvider client={queryClientRef.current}>
<Hydrate state={pageProps.dehydratedState}>
<Component {...pageProps} />
</Hydrate>
</QueryClientProvider>
)
}
BUT, I also need to store some fetch calls IN the "cache" in the MyApp.getInitialProps.... how is that gonna happen IF I create an instance with useRef in function above? Meaning, how is my "getInitialProps" gonna get that instance?
MyApp.getInitialProps = async (appContext) => {
// in here, I do a fetch and get some data I need for SSR
// user Session etc...
const { user } = await fetchUserSession();
// WHAT INSTANCE IS THIS?
queryClient.setQueryData('user', user || {});
return {
...appProps,
dehydratedState: dehydrate(queryClient),
}
}
I am currently defining queryClient = new QueryClient() at the top of the page, so "both" can use it. But I think that is causing some issues with hydration when I npm run build this app.
Remember, this is in "_app.js" so I have to use getInitialProps.
The reason I am doing it here is because we need the users session sitewide, no matter what page they and on. So, rather than do this in every single /page/, just do it in _app.js, so the whole site needs that? The /page/ are Static Generated.
for prefetching on the server, you just create a new QueryClient like described further down on the page you have linked:
export async function getStaticProps() {
const queryClient = new QueryClient()
await queryClient.prefetchQuery('posts', getPosts)
return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
}
Here, you create a new empty client, prefetch and take the state and dehydrate it. Then, on the frontend, that state is put into your instance client from MyApp. This is just a way of getting the data from that server-side cache into the client-side cache.

Is there a way to delay deletion of a Firebase user and their associated data?

I'm creating a Flutter app that is using Firebase as a backend for authentication with firestore as a database and storage for larger files to store some user data. I want to allow users to delete their account and all associated data, but I don't want this to be done immediately so that users can recover their account if they decide to come back within 15 days or so.
I originally thought I could do this with a Firebase Function that I could call from my app, which is shown here:
import * as functions from 'firebase-functions';
const admin = require('firebase-admin');
admin.initializeApp();
const fifteenDays = 1296000000;
export const helloWorld = functions.https.onCall((data, context) => {
setTimeout(async () => {
try {
await admin.auth().deleteUser(data.id);
console.log(`Deleted User: ${data.id}`);
await admin.firestore().collection("users").document(data.id).delete();
console.log(`Deleted User Firestore: ${data.id}`);
await admin.storage().bucket().deleteFiles({
prefix: `userPhotos/${data.id}/`,
force: true,
},
function(err: any) {
if (err) {
console.log(err);
}
else {
console.log(`All the Firebase Storage files in users/${data.id}/ have been deleted`);
}
}
);
}
catch (error) {
console.log(error);
}
}, fifteenDays);
});
But after reading Firebase Functions Tips & tricks to find a method of cancelling the timeout, I saw that code run after function termination can't access the CPU so this code won't even work.
Does anyone have any suggestions of a method in achieving what I need with the ability to cancel the scheduled deletion? Any free solution would be helpful.
You could always create a collection of, for example, "Users_to_delete", and in the documents insert the user ID and the date to delete it.
For example
Users_to_delete
|----Document ID
|-------- UserID
|-------- Date_to_delete
Then run a function every day/hour in cloud functions that checks the collection filtering with the current day and deleting every user that is there.

Bulk import/export in Cloud Fire Store [duplicate]

Is there a way to import CSV or JSON to firebase cloud firestore like in firebase realtime database?
General Solution
I've found many takes on a script allowing to upload a JSON but none of them allowed sub-collections. My script above handles any level of nesting and sub-collections. It also handles the case where a document has its own data and sub-collections. This is based on the assumption that collection is array/object of objects (including an empty object or array).
To run the script make sure you have npm and node installed. Then run your code as node <name of the file>. Note, there is no need to deploy it as a cloud funciton.
const admin = require('../functions/node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<your-database-name>.firebaseio.com"
});
const data = require("./fakedb.json");
/**
* Data is a collection if
* - it has a odd depth
* - contains only objects or contains no objects.
*/
function isCollection(data, path, depth) {
if (
typeof data != 'object' ||
data == null ||
data.length === 0 ||
isEmpty(data)
) {
return false;
}
for (const key in data) {
if (typeof data[key] != 'object' || data[key] == null) {
// If there is at least one non-object item in the data then it cannot be collection.
return false;
}
}
return true;
}
// Checks if object is empty.
function isEmpty(obj) {
for(const key in obj) {
if(obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
async function upload(data, path) {
return await admin.firestore()
.doc(path.join('/'))
.set(data)
.then(() => console.log(`Document ${path.join('/')} uploaded.`))
.catch(() => console.error(`Could not write document ${path.join('/')}.`));
}
/**
*
*/
async function resolve(data, path = []) {
if (path.length > 0 && path.length % 2 == 0) {
// Document's length of path is always even, however, one of keys can actually be a collection.
// Copy an object.
const documentData = Object.assign({}, data);
for (const key in data) {
// Resolve each collection and remove it from document data.
if (isCollection(data[key], [...path, key])) {
// Remove a collection from the document data.
delete documentData[key];
// Resolve a colleciton.
resolve(data[key], [...path, key]);
}
}
// If document is empty then it means it only consisted of collections.
if (!isEmpty(documentData)) {
// Upload a document free of collections.
await upload(documentData, path);
}
} else {
// Collection's length of is always odd.
for (const key in data) {
// Resolve each collection.
await resolve(data[key], [...path, key]);
}
}
}
resolve(data);
You need a custom script to do that.
I wrote one based on the Firebase admin SDK, as long as firebase library does not allow you to import nested arrays of data.
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");
const data = require("./data.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://YOUR_DB.firebaseio.com"
});
data && Object.keys(data).forEach(key => {
const nestedContent = data[key];
if (typeof nestedContent === "object") {
Object.keys(nestedContent).forEach(docTitle => {
admin.firestore()
.collection(key)
.doc(docTitle)
.set(nestedContent[docTitle])
.then((res) => {
console.log("Document successfully written!");
})
.catch((error) => {
console.error("Error writing document: ", error);
});
});
}
});
Update: I wrote an article on this topic - Filling Firestore with data
There is not, you'll need to write your own script at this time.
I used the General Solution provided by Maciej Caputa. Thank you (:
Here are a few hints. Assuming that you have an Ionic Firebase application installed with the required Firebase node modules in the functions folder inside that solution. This is a standard Ionic Firebase install. I created an import folder to hold the script and data at the same level.
Folder Hierarchy
myIonicApp
functions
node_modules
firebase-admin
ImportFolder
script.js
FirebaseIonicTest-a1b2c3d4e5.json
fileToImport.json
Script Parameters
const admin = require('../myIonicApp/functions/node_modules/firebase-admin'); //path to firebase-admin module
const serviceAccount = require("./FirebaseTest-xxxxxxxxxx.json"); //service account key file
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://fir-test-xxxxxx.firebaseio.com" //Your domain from the hosting tab
});
Creating the Service Account Key File
In the Firebase console for your project, next to the Project
Overwiew item, click on the gear icon and select Users and
permissions
At the bottom of the screen, click Advanced permission
settings
This opens another tab for the Google Cloud Platform Console
On the left select the Service Accounts item
Create a Service Account for an existing Service Account
I simply added a key to the App Engine default service account
The Create key function will offer to download the key to a JSON file
JSON Data Structure
To use the script provided, the data structure must be as follows:
{
"myCollection" : {
"UniqueKey1" : {
"field1" : "foo",
"field2" : "bar"
},{
"UniqueKey2" : {
"field1" : "fog",
"field2" : "buzz"
}...
}
For reference. I wrote a function that helps to import and export data in Firestore.
https://github.com/dalenguyen/firestore-import-export (archived)
Updated 2023:
Use this package instead. Thanks, #Webber
https://github.com/dalenguyen/firestore-backup-restore
https://gist.github.com/JoeRoddy/1c706b77ca676bfc0983880f6e9aa8c8
This should work for an object of objects (generally how old firebase json is set up). You can add that code to an app that's already configured with Firestore.
Just make sure you have it pointing to the correct JSON file.
Good luck!
This workaround in Python may help some people. First convert json or csv to dataframe using Pandas, then convert dataframe to dictionary and upload dictionary to firestore.
import firebase_admin as fb
from firebase_admin import firestore
import pandas as pd
cred = fb.credentials.Certificate('my_credentials_certificate.json')
default_app = fb.initialize_app(cred)
db = firestore.client()
df = pd.read_csv('data.csv')
dict = df.to_dict(orient='records')
my_doc_ref = db.collection('my_collection').document('my_document')
my_doc_ref.set(dict)
There could be similar workarounds in javascript and other languages using libraries similar to Pandas.
No as of now, you can't.. firestore structures data into a different format that is, using collections and each collection has a series of documents which then are stored in JSON format.. in future they might make a tool to convert JSON in to firestore.. for reference check this out
:https://cloud.google.com/firestore/docs/concepts/structure-data
****EDIT :****
You can automate the process up to some extent, that is, write a mock software which only pushes the fields of your CSV or JSON data into your Cloud Firestore DB. I migrated my whole database my making just a simple app which retrieved my DB and pushed it on Firestore
var admin = require('firebase-admin');
var serviceAccount = require('./serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://csvread-d149c.firebaseio.com'
});
const csv = require('csv-parser');
const fs = require('fs');
const firestore = admin.firestore();
// CSV FILE data.csv
// Name,Surname,Age,Gender
// John,Snow,26,M
// Clair,White,33,F
// Fancy,Brown,78,F
fs.createReadStream('data.csv')
.pipe(csv())
.on('data', (row) => {
console.log(row);
if(row) {
firestore.collection('csv').add({
name: row.Name,
surname: row.Surname,
age: row.Age,
sex: row.Gender
});
}
else {
console.log('No data')
}
})
.on('end', () => {
console.log('CSV file successfully processed');
});
There is now a paid GUI tool that does this, Firefoo. I haven't used it, but it seems quite powerful for managing Firestore - including importing csv files:
This is a small modification that copies the 'id' of the document, if exists, to its path. Otherwise it will use the "for"'s index.
...
...
} else {
// Collection's length of is always odd.
for (const key in data) {
// Resolve each collection.
if (data[key]['id']!==undefined)
await resolve(data[key], [...path,data[key]['id']])
else
await resolve(data[key], [...path, key]);
}
}
}
resolve(data);
1 - Importing only collections
If the names of your collections are not only composed of numbers, then you can define the name of the document as follows.
...
...
} else {
// Collection's length of is always odd.
for (const key in data) {
// // Resolve each collection.
// If key is a number it means that it is not a collection
// The variable id in this case will be the name of the document field or you
// can generate randomly
let id = !isNaN(key) ? data[key].id : key;
await resolve(data[key], [...path, id]);
}
}
}
2 - Import collections and sub-collections
In the same way as in the example above, the name of the sub-collection can not contain only numbers.
...
...
for (const key in data) {
// Resolve each collection and remove it from document data.
if (isCollection(data[key], [...path, key])) {
// Remove a collection from the document data.
delete documentData[key];
// If key is a number it means that it is not a collection
// The variable id in this case will be the name of the document field or you
// can generate randomly
let id = !isNaN(key) ? data[key].id : key;
// Resolve a colleciton.
resolve(data[key], [...path, id]);
}
}
...
...
Note.: Changes in #Maciej Caputa's code
this library you can use https://www.npmjs.com/package/csv-to-firestore
install this library with this command npm i -g csv-to-firestore
put this script inside your ./scripts
module.exports = {
path: "./scripts/palabrasOutput.csv",
firebase: {
credential: "./scripts/serviceAccount.json",
collection: "collectionInFirestore",
},
mapper: (dataFromCSV) => {
return dataFromCSV;
},
};
and run:
csv-to-firestore --config ./scripts/csvToFirestore.js
btw: Generate new private key (it's a file in Service account section in firestore)
put that file in /scripts folder and rename serviceAccount.json

How to import CSV or JSON to firebase cloud firestore

Is there a way to import CSV or JSON to firebase cloud firestore like in firebase realtime database?
General Solution
I've found many takes on a script allowing to upload a JSON but none of them allowed sub-collections. My script above handles any level of nesting and sub-collections. It also handles the case where a document has its own data and sub-collections. This is based on the assumption that collection is array/object of objects (including an empty object or array).
To run the script make sure you have npm and node installed. Then run your code as node <name of the file>. Note, there is no need to deploy it as a cloud funciton.
const admin = require('../functions/node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<your-database-name>.firebaseio.com"
});
const data = require("./fakedb.json");
/**
* Data is a collection if
* - it has a odd depth
* - contains only objects or contains no objects.
*/
function isCollection(data, path, depth) {
if (
typeof data != 'object' ||
data == null ||
data.length === 0 ||
isEmpty(data)
) {
return false;
}
for (const key in data) {
if (typeof data[key] != 'object' || data[key] == null) {
// If there is at least one non-object item in the data then it cannot be collection.
return false;
}
}
return true;
}
// Checks if object is empty.
function isEmpty(obj) {
for(const key in obj) {
if(obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
async function upload(data, path) {
return await admin.firestore()
.doc(path.join('/'))
.set(data)
.then(() => console.log(`Document ${path.join('/')} uploaded.`))
.catch(() => console.error(`Could not write document ${path.join('/')}.`));
}
/**
*
*/
async function resolve(data, path = []) {
if (path.length > 0 && path.length % 2 == 0) {
// Document's length of path is always even, however, one of keys can actually be a collection.
// Copy an object.
const documentData = Object.assign({}, data);
for (const key in data) {
// Resolve each collection and remove it from document data.
if (isCollection(data[key], [...path, key])) {
// Remove a collection from the document data.
delete documentData[key];
// Resolve a colleciton.
resolve(data[key], [...path, key]);
}
}
// If document is empty then it means it only consisted of collections.
if (!isEmpty(documentData)) {
// Upload a document free of collections.
await upload(documentData, path);
}
} else {
// Collection's length of is always odd.
for (const key in data) {
// Resolve each collection.
await resolve(data[key], [...path, key]);
}
}
}
resolve(data);
You need a custom script to do that.
I wrote one based on the Firebase admin SDK, as long as firebase library does not allow you to import nested arrays of data.
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");
const data = require("./data.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://YOUR_DB.firebaseio.com"
});
data && Object.keys(data).forEach(key => {
const nestedContent = data[key];
if (typeof nestedContent === "object") {
Object.keys(nestedContent).forEach(docTitle => {
admin.firestore()
.collection(key)
.doc(docTitle)
.set(nestedContent[docTitle])
.then((res) => {
console.log("Document successfully written!");
})
.catch((error) => {
console.error("Error writing document: ", error);
});
});
}
});
Update: I wrote an article on this topic - Filling Firestore with data
There is not, you'll need to write your own script at this time.
I used the General Solution provided by Maciej Caputa. Thank you (:
Here are a few hints. Assuming that you have an Ionic Firebase application installed with the required Firebase node modules in the functions folder inside that solution. This is a standard Ionic Firebase install. I created an import folder to hold the script and data at the same level.
Folder Hierarchy
myIonicApp
functions
node_modules
firebase-admin
ImportFolder
script.js
FirebaseIonicTest-a1b2c3d4e5.json
fileToImport.json
Script Parameters
const admin = require('../myIonicApp/functions/node_modules/firebase-admin'); //path to firebase-admin module
const serviceAccount = require("./FirebaseTest-xxxxxxxxxx.json"); //service account key file
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://fir-test-xxxxxx.firebaseio.com" //Your domain from the hosting tab
});
Creating the Service Account Key File
In the Firebase console for your project, next to the Project
Overwiew item, click on the gear icon and select Users and
permissions
At the bottom of the screen, click Advanced permission
settings
This opens another tab for the Google Cloud Platform Console
On the left select the Service Accounts item
Create a Service Account for an existing Service Account
I simply added a key to the App Engine default service account
The Create key function will offer to download the key to a JSON file
JSON Data Structure
To use the script provided, the data structure must be as follows:
{
"myCollection" : {
"UniqueKey1" : {
"field1" : "foo",
"field2" : "bar"
},{
"UniqueKey2" : {
"field1" : "fog",
"field2" : "buzz"
}...
}
For reference. I wrote a function that helps to import and export data in Firestore.
https://github.com/dalenguyen/firestore-import-export (archived)
Updated 2023:
Use this package instead. Thanks, #Webber
https://github.com/dalenguyen/firestore-backup-restore
https://gist.github.com/JoeRoddy/1c706b77ca676bfc0983880f6e9aa8c8
This should work for an object of objects (generally how old firebase json is set up). You can add that code to an app that's already configured with Firestore.
Just make sure you have it pointing to the correct JSON file.
Good luck!
This workaround in Python may help some people. First convert json or csv to dataframe using Pandas, then convert dataframe to dictionary and upload dictionary to firestore.
import firebase_admin as fb
from firebase_admin import firestore
import pandas as pd
cred = fb.credentials.Certificate('my_credentials_certificate.json')
default_app = fb.initialize_app(cred)
db = firestore.client()
df = pd.read_csv('data.csv')
dict = df.to_dict(orient='records')
my_doc_ref = db.collection('my_collection').document('my_document')
my_doc_ref.set(dict)
There could be similar workarounds in javascript and other languages using libraries similar to Pandas.
No as of now, you can't.. firestore structures data into a different format that is, using collections and each collection has a series of documents which then are stored in JSON format.. in future they might make a tool to convert JSON in to firestore.. for reference check this out
:https://cloud.google.com/firestore/docs/concepts/structure-data
****EDIT :****
You can automate the process up to some extent, that is, write a mock software which only pushes the fields of your CSV or JSON data into your Cloud Firestore DB. I migrated my whole database my making just a simple app which retrieved my DB and pushed it on Firestore
var admin = require('firebase-admin');
var serviceAccount = require('./serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://csvread-d149c.firebaseio.com'
});
const csv = require('csv-parser');
const fs = require('fs');
const firestore = admin.firestore();
// CSV FILE data.csv
// Name,Surname,Age,Gender
// John,Snow,26,M
// Clair,White,33,F
// Fancy,Brown,78,F
fs.createReadStream('data.csv')
.pipe(csv())
.on('data', (row) => {
console.log(row);
if(row) {
firestore.collection('csv').add({
name: row.Name,
surname: row.Surname,
age: row.Age,
sex: row.Gender
});
}
else {
console.log('No data')
}
})
.on('end', () => {
console.log('CSV file successfully processed');
});
There is now a paid GUI tool that does this, Firefoo. I haven't used it, but it seems quite powerful for managing Firestore - including importing csv files:
This is a small modification that copies the 'id' of the document, if exists, to its path. Otherwise it will use the "for"'s index.
...
...
} else {
// Collection's length of is always odd.
for (const key in data) {
// Resolve each collection.
if (data[key]['id']!==undefined)
await resolve(data[key], [...path,data[key]['id']])
else
await resolve(data[key], [...path, key]);
}
}
}
resolve(data);
1 - Importing only collections
If the names of your collections are not only composed of numbers, then you can define the name of the document as follows.
...
...
} else {
// Collection's length of is always odd.
for (const key in data) {
// // Resolve each collection.
// If key is a number it means that it is not a collection
// The variable id in this case will be the name of the document field or you
// can generate randomly
let id = !isNaN(key) ? data[key].id : key;
await resolve(data[key], [...path, id]);
}
}
}
2 - Import collections and sub-collections
In the same way as in the example above, the name of the sub-collection can not contain only numbers.
...
...
for (const key in data) {
// Resolve each collection and remove it from document data.
if (isCollection(data[key], [...path, key])) {
// Remove a collection from the document data.
delete documentData[key];
// If key is a number it means that it is not a collection
// The variable id in this case will be the name of the document field or you
// can generate randomly
let id = !isNaN(key) ? data[key].id : key;
// Resolve a colleciton.
resolve(data[key], [...path, id]);
}
}
...
...
Note.: Changes in #Maciej Caputa's code
this library you can use https://www.npmjs.com/package/csv-to-firestore
install this library with this command npm i -g csv-to-firestore
put this script inside your ./scripts
module.exports = {
path: "./scripts/palabrasOutput.csv",
firebase: {
credential: "./scripts/serviceAccount.json",
collection: "collectionInFirestore",
},
mapper: (dataFromCSV) => {
return dataFromCSV;
},
};
and run:
csv-to-firestore --config ./scripts/csvToFirestore.js
btw: Generate new private key (it's a file in Service account section in firestore)
put that file in /scripts folder and rename serviceAccount.json

Resources