Socket
Socket
Sign inDemoInstall

firestore-export-import

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

firestore-export-import - npm Package Compare versions

Comparing version 0.3.1 to 0.3.2

34

CHANGELOG.md
# Change log
> **Tags:**
> - :boom: [Breaking Change]
>
> - :boom: [Breaking Change]
> - :eyeglasses: [Spec Compliancy]
> - :rocket: [New Feature]
> - :bug: [Bug Fix]
> - :memo: [Documentation]
> - :nail_care: [Polish]
> - :rocket: [New Feature]
> - :bug: [Bug Fix]
> - :memo: [Documentation]
> - :nail_care: [Polish]
---
## [0.3.2] - 2020-01-03
#### - :rocket: [New Feature]
- Get data with all sub collectiosn with extra params
#### - :nail_care: [Polish]
- Updated packages
## [0.3.1] - 2019-11-11
#### - :bug: [Bug Fix]
#### - :bug: [Bug Fix]
- Allow multi level time #33
## [0.3.0] - 2019-11-11
#### - :nail_care: [Polish]
#### - :nail_care: [Polish]
- Update packages
- Added change log
#### - :rocket: [New Feature]
- Support time import max to two levels
#### - :rocket: [New Feature]
- Support time import max to two levels

@@ -11,5 +11,4 @@ /**

* @param {string} collectionName
* @param {string} [subCollection='']
* @returns {Promise<any>}
*/
export declare const backup: (collectionName: string, subCollection?: string) => Promise<any>;
export declare const backup: (collectionName: string) => Promise<any>;

@@ -15,5 +15,2 @@ "use strict";var __awaiter=(this&&this.__awaiter)||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value);});}

r[k]=a[j];return r;};var __importStar=(this&&this.__importStar)||function(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null)for(var k in mod)if(Object.hasOwnProperty.call(mod,k))result[k]=mod[k];result["default"]=mod;return result;};Object.defineProperty(exports,"__esModule",{value:true});var admin=__importStar(require("firebase-admin"));exports.getAllCollections=function(collectionNameArray){var db=admin.firestore();return new Promise(function(resolve){db.listCollections().then(function(snap){var paths=collectionNameArray;if(paths.length===0){snap.forEach(function(collection){return paths.push(collection.path);});}
var promises=[];paths.forEach(function(segment){var result=exports.backup(segment);promises.push(result);});Promise.all(promises).then(function(value){var all=Object.assign.apply(Object,__spreadArrays([{}],value));resolve(all);});});});};exports.backup=function(collectionName,subCollection){if(subCollection===void 0){subCollection='';}
return new Promise(function(resolve,reject){var db=admin.firestore();var data={};data[collectionName]={};var results=db.collection(collectionName).get().then(function(snapshot){snapshot.forEach(function(doc){data[collectionName][doc.id]=doc.data();});return data;}).catch(function(error){console.log(error);});results.then(function(dt){if(subCollection===''){resolve(dt);}
else{console.log('Geting sub collection',subCollection);getSubCollection(db,data,dt,collectionName,subCollection).then(function(){resolve(data);}).catch(function(error){console.log(error);reject(error);});}}).catch(function(error){console.log(error);reject(error);});});};var getSubCollection=function(db,data,dt,collectionName,subCollection){return __awaiter(void 0,void 0,void 0,function(){var _i,_a,_b,key,value,subCollectionPath,subCollectionData;return __generator(this,function(_c){switch(_c.label){case 0:_i=0,_a=Object.entries([dt[collectionName]][0]);_c.label=1;case 1:if(!(_i<_a.length))return[3,4];_b=_a[_i],key=_b[0],value=_b[1];subCollectionPath=collectionName+'/'+key+'/'+subCollection;return[4,exports.backup(subCollectionPath)];case 2:subCollectionData=_c.sent();if(Object.keys(subCollectionData[subCollectionPath]).length>0){data[collectionName][key]['subCollection']=subCollectionData;}
_c.label=3;case 3:_i++;return[3,1];case 4:return[2];}});});};
var promises=[];paths.forEach(function(segment){var result=exports.backup(segment);promises.push(result);});Promise.all(promises).then(function(value){var all=Object.assign.apply(Object,__spreadArrays([{}],value));resolve(all);});});});};exports.backup=function(collectionName){return __awaiter(void 0,void 0,void 0,function(){var db,data,documents,_i,_a,doc,subCollections,_b,subCollections_1,subCol,subColData,error_1;return __generator(this,function(_c){switch(_c.label){case 0:_c.trys.push([0,9,,10]);db=admin.firestore();data={};data[collectionName]={};return[4,db.collection(collectionName).get()];case 1:documents=_c.sent();_i=0,_a=documents.docs;_c.label=2;case 2:if(!(_i<_a.length))return[3,8];doc=_a[_i];return[4,doc.ref.listCollections()];case 3:subCollections=_c.sent();data[collectionName][doc.id]=doc.data();_b=0,subCollections_1=subCollections;_c.label=4;case 4:if(!(_b<subCollections_1.length))return[3,7];subCol=subCollections_1[_b];return[4,exports.backup(collectionName+"/"+doc.id+"/"+subCol.id)];case 5:subColData=_c.sent();data[collectionName][doc.id]['subCollection']=subColData;_c.label=6;case 6:_b++;return[3,4];case 7:_i++;return[3,2];case 8:return[2,data];case 9:error_1=_c.sent();console.error(error_1);throw new Error(error_1);case 10:return[2];}});});};

@@ -14,6 +14,5 @@ import * as admin from 'firebase-admin';

* @param {string} collectionName
* @param {string} subCollection
* @return {json}
*/
export declare const backup: (collectionName: string, subCollection?: string) => Promise<any>;
export declare const backup: (collectionName: string) => Promise<any>;
/**

@@ -20,0 +19,0 @@ * Restore data to firestore

@@ -1,5 +0,4 @@

"use strict";var __importStar=(this&&this.__importStar)||function(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null)for(var k in mod)if(Object.hasOwnProperty.call(mod,k))result[k]=mod[k];result["default"]=mod;return result;};Object.defineProperty(exports,"__esModule",{value:true});var admin=__importStar(require("firebase-admin"));exports.admin=admin;var restoreService=__importStar(require("./import"));var backupService=__importStar(require("./export"));exports.initializeApp=function(serviceAccount,databaseURL){admin.initializeApp({credential:admin.credential.cert(serviceAccount),databaseURL:databaseURL});admin.firestore().settings({timestampsInSnapshots:true});return true;};exports.backup=function(collectionName,subCollection){if(subCollection===void 0){subCollection='';}
return backupService.backup(collectionName,subCollection);};exports.restore=function(fileName,dateArray,geoArray){if(dateArray===void 0){dateArray=[];}
"use strict";var __importStar=(this&&this.__importStar)||function(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null)for(var k in mod)if(Object.hasOwnProperty.call(mod,k))result[k]=mod[k];result["default"]=mod;return result;};Object.defineProperty(exports,"__esModule",{value:true});var admin=__importStar(require("firebase-admin"));exports.admin=admin;var restoreService=__importStar(require("./import"));var backupService=__importStar(require("./export"));exports.initializeApp=function(serviceAccount,databaseURL){admin.initializeApp({credential:admin.credential.cert(serviceAccount),databaseURL:databaseURL});admin.firestore().settings({timestampsInSnapshots:true});return true;};exports.backup=function(collectionName){return backupService.backup(collectionName);};exports.restore=function(fileName,dateArray,geoArray){if(dateArray===void 0){dateArray=[];}
if(geoArray===void 0){geoArray=[];}
return restoreService.restore(fileName,dateArray,geoArray);};exports.backups=function(collectionNameArray){if(collectionNameArray===void 0){collectionNameArray=[];}
return backupService.getAllCollections(collectionNameArray);};
{
"name": "firestore-export-import",
"version": "0.3.1",
"version": "0.3.2",
"description": "NPM package for backup and restore Firebase Firestore",

@@ -31,5 +31,5 @@ "main": "dist/index.js",

"devDependencies": {
"@types/chai": "^4.2.4",
"@types/chai": "^4.2.7",
"@types/mocha": "^5.2.7",
"@types/node": "^12.12.7",
"@types/node": "^13.1.2",
"chai": "^4.2.0",

@@ -40,7 +40,7 @@ "jsmin": "^1.0.1",

"request-promise": "^4.2.5",
"ts-node": "^8.5.0",
"typescript": "^3.7.2"
"ts-node": "^8.5.4",
"typescript": "^3.7.4"
},
"dependencies": {
"firebase-admin": "^8.7.0"
"firebase-admin": "^8.9.0"
},

@@ -47,0 +47,0 @@ "engines": {

# firestore-export-import
[![GitHub version](https://badge.fury.io/gh/dalenguyen%2Ffirestore-backup-restore.svg)](https://badge.fury.io/gh/dalenguyen%2Ffirestore-backup-restore)
[![GitHub version](https://badge.fury.io/gh/dalenguyen%2Ffirestore-backup-restore.svg)](https://badge.fury.io/gh/dalenguyen%2Ffirestore-backup-restore)
[![Build Status](https://travis-ci.org/dalenguyen/firestore-backup-restore.svg?branch=master)](https://travis-ci.org/dalenguyen/firestore-backup-restore)

@@ -9,7 +9,7 @@ [![David badge](https://david-dm.org/dalenguyen/firestore-backup-restore.svg)](https://david-dm.org/dalenguyen/firestore-backup-restore)

You can export and import data from firestore with sub collection.
You can export and import data from firestore with sub collection.
## Installation
## Installation
Install using [__npm__](https://www.npmjs.com/).
Install using [**npm**](https://www.npmjs.com/).

@@ -22,5 +22,5 @@ ```sh

You can __Generate New Private Key__ from Project Settings from [Firebase Console](https://console.firebase.google.com).
You can **Generate New Private Key** from Project Settings from [Firebase Console](https://console.firebase.google.com).
After that you need to copy the __databaseURL__ for initiating the App.
After that you need to copy the **databaseURL** for initiating the App.

@@ -46,7 +46,7 @@ ## Usage

firestoreService
.backup('collection-name', 'sub-collection-optional')
.then(data => console.log(JSON.stringify(data)))
.backup('collection-name')
.then(data => console.log(JSON.stringify(data)));
```
If the sub collection exists, it will be saved under __subCollection__.
Sub collections will be added under **'subCollection'** object.

@@ -67,4 +67,3 @@ ### Get all collections data

console.log(JSON.stringify(collections));
})
});
```

@@ -74,6 +73,6 @@

This code will help you to import data from a JSON file to firestore. You have two options:
This code will help you to import data from a JSON file to firestore. You have two options:
+ Restore from a JSON file from your local machine
+ Restore from a JSON from a HTTP request
- Restore from a JSON file from your local machine
- Restore from a JSON from a HTTP request

@@ -101,6 +100,10 @@ This will return a Promise<{status: boolean, message: string}>

// The array of date and location fields are optional
firestoreService.restore('your-file-path.json', ['date1', 'date2.date3'], ['location1', 'location2']);
firestoreService.restore(
'your-file-path.json',
['date1', 'date2.date3'],
['location1', 'location2']
);
```
* Note that the date array only support two levels now. If you pass ['date1.date2.date3'], it won't work.
- Note that the date array only support two levels now. If you pass ['date1.date2.date3'], it won't work.

@@ -116,3 +119,3 @@ #### For HTTP Request

The JSON is formated as below. The collection name is __test__. __first-key__ and __second-key__ are document ids.
The JSON is formated as below. The collection name is **test**. **first-key** and **second-key** are document ids.

@@ -119,0 +122,0 @@ ```json

import * as admin from 'firebase-admin';
/**
* Get data from all collections
* Get data from all collections
* Suggestion from jcummings2 and leningsv

@@ -9,92 +9,60 @@ * @param {Array<string>} collectionNameArray

export const getAllCollections = (collectionNameArray): Promise<any> => {
const db = admin.firestore();
// get all the root-level paths
return new Promise((resolve) => {
db.listCollections().then((snap) => {
let paths = collectionNameArray;
if(paths.length === 0) { // get all collections
snap.forEach((collection) => paths.push(collection.path));
}
// fetch in parallel
let promises = [];
paths.forEach((segment) => {
let result = backup(segment);
promises.push(result);
});
// assemble the pieces into one object
Promise.all(promises).then((value) => {
let all = Object.assign({}, ...value);
resolve(all);
});
});
})
}
const db = admin.firestore();
// get all the root-level paths
return new Promise(resolve => {
db.listCollections().then(snap => {
let paths = collectionNameArray;
if (paths.length === 0) {
// get all collections
snap.forEach(collection => paths.push(collection.path));
}
// fetch in parallel
let promises = [];
paths.forEach(segment => {
let result = backup(segment);
promises.push(result);
});
// assemble the pieces into one object
Promise.all(promises).then(value => {
let all = Object.assign({}, ...value);
resolve(all);
});
});
});
};
/**
* Backup data from firestore
*
* @param {string} collectionName
* @param {string} [subCollection='']
* @returns {Promise<any>}
*
* @param {string} collectionName
* @returns {Promise<any>}
*/
export const backup = (collectionName: string, subCollection: string = ''): Promise<any> => {
return new Promise((resolve, reject) => {
const db = admin.firestore();
let data = {};
export const backup = async (collectionName: string): Promise<any> => {
try {
const db = admin.firestore();
let data = {};
data[collectionName] = {};
data[collectionName] = {};
const documents = await db.collection(collectionName).get();
let results = db.collection(collectionName)
.get()
.then(snapshot => {
snapshot.forEach(doc => {
data[collectionName][doc.id] = doc.data();
})
return data;
})
.catch(error => {
console.log(error);
})
for (const doc of documents.docs) {
const subCollections = await doc.ref.listCollections();
results.then(dt => {
if (subCollection === '') {
resolve(dt);
} else {
console.log('Geting sub collection', subCollection)
getSubCollection(db, data, dt, collectionName, subCollection).then(() => {
resolve(data)
}).catch(error => {
console.log(error);
reject(error);
})
}
}).catch(error => {
console.log(error)
reject(error);
})
})
data[collectionName][doc.id] = doc.data();
}
for (const subCol of subCollections) {
const subColData = await backup(
`${collectionName}/${doc.id}/${subCol.id}`
);
data[collectionName][doc.id]['subCollection'] = subColData;
}
}
/**
* Get sub collection from a document if possible
*
* @param {any} db
* @param {any} data
* @param {any} dt
* @param {any} collectionName
* @param {any} subCollection
*/
const getSubCollection = async (db, data, dt, collectionName, subCollection) => {
for (let [key, value] of Object.entries([dt[collectionName]][0])) {
const subCollectionPath = collectionName + '/' + key + '/' + subCollection;
let subCollectionData = await backup(subCollectionPath)
if (Object.keys(subCollectionData[subCollectionPath]).length > 0) {
data[collectionName][key]['subCollection'] = subCollectionData;
}
}
}
return data;
} catch (error) {
console.error(error);
throw new Error(error);
}
};

@@ -7,37 +7,40 @@ import * as admin from 'firebase-admin';

* Initialize Firebase App
*
* @param {any} serviceAccount
*
* @param {any} serviceAccount
* @param {any} databaseURL
*/
export const initializeApp = (serviceAccount: string, databaseURL: string) => {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
admin.firestore().settings({ timestampsInSnapshots: true });
return true;
}
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
admin.firestore().settings({ timestampsInSnapshots: true });
return true;
};
export { admin }
export { admin };
/**
* Backup data from firestore
*
*
* @param {string} collectionName
* @param {string} subCollection
* @return {json}
*/
export const backup = (collectionName: string, subCollection: string = '') => {
return backupService.backup(collectionName, subCollection);
}
export const backup = (collectionName: string) => {
return backupService.backup(collectionName);
};
/**
* Restore data to firestore
* @param fileName
* @param dateArray
* @param geoArray
* @param fileName
* @param dateArray
* @param geoArray
*/
export const restore = (fileName: string, dateArray: Array<string> = [], geoArray: Array<string> = []) => {
return restoreService.restore(fileName, dateArray, geoArray);
}
export const restore = (
fileName: string,
dateArray: Array<string> = [],
geoArray: Array<string> = []
) => {
return restoreService.restore(fileName, dateArray, geoArray);
};

@@ -49,3 +52,3 @@ /**

export const backups = (collectionNameArray: Array<string> = []) => {
return backupService.getAllCollections(collectionNameArray);
}
return backupService.getAllCollections(collectionNameArray);
};

@@ -6,55 +6,67 @@ import { expect } from 'chai';

const app = firestoreService.initializeApp(serviceAccount, serviceAccount.databaseUrl);
const backupAPI = 'https://firebasestorage.googleapis.com/v0/b/firbase-function-helper-qa.appspot.com/o/import-to-firestore.json?alt=media&token=a0530902-8983-45a4-90c2-72c345c7a3d5';
const app = firestoreService.initializeApp(
serviceAccount,
serviceAccount.databaseUrl
);
const backupAPI =
'https://firebasestorage.googleapis.com/v0/b/firbase-function-helper-qa.appspot.com/o/import-to-firestore.json?alt=media&token=a0530902-8983-45a4-90c2-72c345c7a3d5';
describe ('initializeApp function test', () => {
it ('Initialize app', () => {
expect(app).to.equal(true);
});
describe('initializeApp function test', () => {
it('Initialize app', () => {
expect(app).to.equal(true);
});
it('Get a colection with sub-collection', async () => {
try {
const data = await firestoreService.backup('test', 'details');
const subCol = data['test']['first-key']['subCollection'];
expect(subCol).is.exist;
expect(Object.values(subCol).length).is.greaterThan(0);
} catch (error) {
console.log(error)
}
});
it('Get a colection with sub-collection', async () => {
try {
const data = await firestoreService.backup('test');
const subCol = data['test']['first-key']['subCollection'];
it ('Get all collections', async () => {
try {
const all = await firestoreService.backups();
expect(Object.keys(all).length).is.greaterThan(0);
} catch (error) {
console.log(error)
}
});
expect(subCol).is.exist;
expect(Object.values(subCol).length).is.greaterThan(0);
} catch (error) {
console.log(error);
}
});
it ('Get an array of collections', async () => {
const all = await firestoreService.backups(['test', 'users']);
expect(Object.keys(all).length).is.equal(2);
});
it('Get all collections', async () => {
try {
const all = await firestoreService.backups();
expect(Object.keys(all).length).is.greaterThan(0);
} catch (error) {
console.log(error);
}
});
it ('Restore data', async () => {
let status = await firestoreService.restore('test/import-to-firestore.json', ['date', 'schedule.time', 'three.level.time'], ['location']);
expect(status.status).ok;
const result = await firestoreService.backup('test');
expect(result.test['first-key'].email).is.equal('dungnq@itbox4vn.com');
expect(result.test['first-key'].schedule.time._seconds).equals(1534046400)
});
it('Get an array of collections', async () => {
const all = await firestoreService.backups(['test', 'users']);
expect(Object.keys(all).length).is.equal(2);
});
it ('Restore data from API', async () => {
const backupData = await request(backupAPI);
const status = await firestoreService.restore(JSON.parse(backupData), ['date'], ['location']);
expect(status.status).ok;
})
it('Restore data', async () => {
let status = await firestoreService.restore(
'test/import-to-firestore.json',
['date', 'schedule.time', 'three.level.time'],
['location']
);
expect(status.status).ok;
it ('Get one collection', async () => {
const result = await firestoreService.backup('test');
expect(Object.keys(result).length).is.equal(1);
});
})
const result = await firestoreService.backup('test');
expect(result.test['first-key'].email).is.equal('dungnq@itbox4vn.com');
expect(result.test['first-key'].schedule.time._seconds).equals(1534046400);
});
it('Restore data from API', async () => {
const backupData = await request(backupAPI);
const status = await firestoreService.restore(
JSON.parse(backupData),
['date'],
['location']
);
expect(status.status).ok;
});
it('Get one collection', async () => {
const result = await firestoreService.backup('test');
expect(Object.keys(result).length).is.equal(1);
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc