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.2 to 0.3.3

test/import-array-to-firestore.json

16

CHANGELOG.md

@@ -14,2 +14,18 @@ # Change log

## [0.3.3] - 2020-01-03
#### - :nail_care: [Polish]
- Update new packages
- Check app before initializing
#### - :boom: [Breaking Change]
- Changed options for date & location & ref
#### - :rocket: [New Feature]
- Added support reference type
- Added upload array of document feature (without predefined document id)
## [0.3.2] - 2020-01-03

@@ -16,0 +32,0 @@

10

dist/import.d.ts

@@ -0,1 +1,6 @@

export interface IImportOptions {
dates?: string[];
geos?: string[];
refs?: string[];
}
/**

@@ -5,5 +10,4 @@ * Restore data to firestore

* @param {string} fileName
* @param {Array<string>} dateArray
* @param {Array<string>} geoArray
* @param {IImportOptions} options
*/
export declare const restore: (fileName: string, dateArray: string[], geoArray: string[]) => Promise<any>;
export declare const restore: (fileName: string, options: IImportOptions) => Promise<any>;

@@ -12,12 +12,13 @@ "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);});}

op=body.call(thisArg,_);}catch(e){op=[6,e];y=0;}finally{f=t=0;}
if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true};}};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"));var fs=__importStar(require("fs"));var updateTime=function(dateArray,documentObj){dateArray.forEach(function(c){c.split(".").reduce(function(acc,cur,i,a){if(!a[i+1]&&acc[cur]&&acc[cur]._seconds){acc[cur]=new Date(acc[cur]._seconds*1000);}
if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true};}};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 fs=__importStar(require("fs"));var uuid_1=require("uuid");var admin=__importStar(require("firebase-admin"));var updateTime=function(dateArray,documentObj){dateArray.forEach(function(c){c.split('.').reduce(function(acc,cur,i,a){if(!a[i+1]&&acc[cur]&&acc[cur]._seconds){acc[cur]=new Date(acc[cur]._seconds*1000);}
else
return acc[cur]||{};},documentObj);});};exports.restore=function(fileName,dateArray,geoArray){var db=admin.firestore();return new Promise(function(resolve,reject){if(typeof fileName==="object"){var dataArray=fileName;updateCollection(db,dataArray,dateArray,geoArray).then(function(){resolve({status:true,message:"Collection successfully imported!"});}).catch(function(error){reject({status:false,message:error.message});});}
else{fs.readFile(fileName,"utf8",function(err,data){if(err){console.log(err);reject({status:false,message:err.message});}
var dataArray=JSON.parse(data);updateCollection(db,dataArray,dateArray,geoArray).then(function(){resolve({status:true,message:"Collection successfully imported!"});}).catch(function(error){reject({status:false,message:error.message});});});}});};var updateCollection=function(db,dataArray,dateArray,geoArray){return __awaiter(void 0,void 0,void 0,function(){var _a,_b,_i,index,collectionName,_c,_d,_e,doc,subCollections;return __generator(this,function(_f){switch(_f.label){case 0:_a=[];for(_b in dataArray)
return acc[cur]||{};},documentObj);});};exports.restore=function(fileName,options){var db=admin.firestore();return new Promise(function(resolve,reject){if(typeof fileName==='object'){var dataArray=fileName;updateCollection(db,dataArray,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});}
else{fs.readFile(fileName,'utf8',function(err,data){if(err){console.log(err);reject({status:false,message:err.message});}
var dataArray=JSON.parse(data);updateCollection(db,dataArray,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});});}}).catch(function(error){return console.error(error);});};var updateCollection=function(db,dataArray,options){if(options===void 0){options={};}
return __awaiter(void 0,void 0,void 0,function(){var _a,_b,_i,index,collectionName,_c,_d,_e,doc,docId,subCollections;return __generator(this,function(_f){switch(_f.label){case 0:_a=[];for(_b in dataArray)
_a.push(_b);_i=0;_f.label=1;case 1:if(!(_i<_a.length))return[3,9];index=_a[_i];collectionName=index;_c=[];for(_d in dataArray[index])
_c.push(_d);_e=0;_f.label=2;case 2:if(!(_e<_c.length))return[3,8];doc=_c[_e];if(!dataArray[index].hasOwnProperty(doc))return[3,7];if(!dataArray[index][doc]["subCollection"])return[3,5];subCollections=dataArray[index][doc]["subCollection"];delete dataArray[index][doc]["subCollection"];return[4,startUpdating(db,collectionName,doc,dataArray[index][doc],dateArray,geoArray)];case 3:_f.sent();return[4,updateCollection(db,subCollections,[],[])];case 4:_f.sent();return[3,7];case 5:return[4,startUpdating(db,collectionName,doc,dataArray[index][doc],dateArray,geoArray)];case 6:_f.sent();_f.label=7;case 7:_e++;return[3,2];case 8:_i++;return[3,1];case 9:return[2];}});});};var startUpdating=function(db,collectionName,doc,data,dateArray,geoArray){var parameterValid=true;if(typeof dateArray==="object"&&dateArray.length>0){updateTime(dateArray,data);}
if(typeof geoArray!=="undefined"&&geoArray.length>0){geoArray.forEach(function(geo){if(data.hasOwnProperty(geo)){data[geo]=new admin.firestore.GeoPoint(data[geo]._latitude,data[geo]._longitude);}
else{console.log("Please check your geo parameters!!!",geoArray);parameterValid=false;}});}
if(parameterValid){return new Promise(function(resolve){db.collection(collectionName).doc(doc).set(data).then(function(){console.log(doc+" was successfully added to firestore!");resolve("Data written!");}).catch(function(error){console.log(error);});});}
else{console.log(doc+" was not imported to firestore. Please check your parameters or ignore if you don't need to import the property above.");return false;}};
_c.push(_d);_e=0;_f.label=2;case 2:if(!(_e<_c.length))return[3,8];doc=_c[_e];if(!dataArray[index].hasOwnProperty(doc))return[3,7];docId=Array.isArray(dataArray[index])?uuid_1.v1():doc;if(!dataArray[index][doc]['subCollection'])return[3,5];subCollections=dataArray[index][docId]['subCollection'];delete dataArray[index][doc]['subCollection'];return[4,startUpdating(db,collectionName,docId,dataArray[index][doc],options)];case 3:_f.sent();return[4,updateCollection(db,subCollections)];case 4:_f.sent();return[3,7];case 5:return[4,startUpdating(db,collectionName,docId,dataArray[index][doc],options)];case 6:_f.sent();_f.label=7;case 7:_e++;return[3,2];case 8:_i++;return[3,1];case 9:return[2];}});});};var startUpdating=function(db,collectionName,docId,data,options){if(options.dates&&options.dates.length>0){updateTime(options.dates,data);}
if(options.refs&&options.refs.length>0){options.refs.forEach(function(ref){if(data.hasOwnProperty(ref)){data[ref]=db.doc(data[ref]);}});}
if(options.geos&&options.geos.length>0){options.geos.forEach(function(geo){if(data.hasOwnProperty(geo)){data[geo]=new admin.firestore.GeoPoint(data[geo]._latitude,data[geo]._longitude);}
else{console.warn('Please check your geo parameters!!!',options.geos);}});}
return new Promise(function(resolve,reject){db.collection(collectionName).doc(docId).set(data).then(function(){console.log(docId+" was successfully added to firestore!");resolve({status:true,message:docId+" was successfully added to firestore!"});}).catch(function(error){console.log(error);reject({status:false,message:error.message});});});};
import * as admin from 'firebase-admin';
import * as restoreService from './import';
/**

@@ -20,6 +21,5 @@ * Initialize Firebase App

* @param fileName
* @param dateArray
* @param geoArray
* @param options
*/
export declare const restore: (fileName: string, dateArray?: string[], geoArray?: string[]) => Promise<any>;
export declare const restore: (fileName: string, options?: restoreService.IImportOptions) => Promise<any>;
/**

@@ -26,0 +26,0 @@ * Get all collections data

@@ -1,4 +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){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=[];}
"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){if(admin.apps.length===0){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,options){if(options===void 0){options={};}
return restoreService.restore(fileName,options);};exports.backups=function(collectionNameArray){if(collectionNameArray===void 0){collectionNameArray=[];}
return backupService.getAllCollections(collectionNameArray);};
{
"name": "firestore-export-import",
"version": "0.3.2",
"version": "0.3.3",
"description": "NPM package for backup and restore Firebase Firestore",

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

"devDependencies": {
"@types/chai": "^4.2.7",
"@types/mocha": "^5.2.7",
"@types/node": "^13.1.2",
"@types/chai": "^4.2.10",
"@types/mocha": "^7.0.2",
"@types/node": "^13.9.0",
"chai": "^4.2.0",
"jsmin": "^1.0.1",
"mocha": "^6.2.2",
"request": "^2.88.0",
"mocha": "^7.1.0",
"request": "^2.88.2",
"request-promise": "^4.2.5",
"ts-node": "^8.5.4",
"typescript": "^3.7.4"
"ts-node": "^8.6.2",
"typescript": "^3.8.3"
},
"dependencies": {
"firebase-admin": "^8.9.0"
"firebase-admin": "^8.9.2"
},

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

@@ -17,2 +17,4 @@ # firestore-export-import

npm install firestore-export-import
OR
yarn add firestore-export-import
```

@@ -68,3 +70,3 @@

### Import data to firestore
### Import data to firestore (Predefined Document Id)

@@ -86,3 +88,16 @@ This code will help you to import data from a JSON file to firestore. You have two options:

Usually the date, location & reference is not converted correctly when you backup the Firestore database. In order to import correctly, you have to pass to parameters for the options:
```javascript
// Import options
const optons = {
dates: ['date1', 'date1.date2', 'date1.date2.date3'],
geos: ['location1', 'location2'],
refs: ['refKey']
};
```
After that, the data will be converted based on their types.
```javascript
// In your index.js

@@ -98,11 +113,9 @@

// 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', {
dates: ['date1', 'date1.date2', 'date1.date2.date3'],
geos: ['location1', 'location2'],
refs: ['refKey']
});
```
- Note that the date array only support two levels now. If you pass ['date1.date2.date3'], it won't work.
#### For HTTP Request

@@ -114,3 +127,6 @@

const backupData = await request('JSON-URL');
const status = await firestoreService.restore(JSON.parse(backupData), ['date'], ['location']);
const status = await firestoreService.restore(JSON.parse(backupData), {
dates: ['date'],
geos: ['location']
});
```

@@ -135,2 +151,10 @@

},
"three": {
"level": {
"time": {
"_seconds": 1534046400,
"_nanoseconds": 0
}
}
},
"custom": {

@@ -145,2 +169,3 @@ "lastName": "Nguyen",

"email": "dungnq@itbox4vn.com",
"secondRef": "test/second-key",
"subCollection": {

@@ -179,4 +204,28 @@ "test/first-key/details": {

### Import data to firestore (auto generate document id)
It works the same way as above. However the structure of JSON file is different. It's an array of documents.
```json
// import-array-to-firestore.json
{
"test": [
{
"name": "Dale Nguyen",
"email": "dale@dalenguyen.me"
},
{
"name": "Yen Nguyen",
"email": "yenchan@gmail.com"
},
{
"name": "Harry Potter",
"email": "harry@potter.me"
}
]
}
```
## Contributions
This project is based on [firestore-import-export](https://github.com/dalenguyen/firestore-import-export), feel free to report bugs and make feature requests in the [Issue Tracker](https://github.com/dalenguyen/firestore-backup-restore/issues), fork and create pull requests!

@@ -1,12 +0,19 @@

import * as admin from "firebase-admin";
import * as fs from "fs";
import * as fs from 'fs';
import { v1 as uuidv1 } from 'uuid';
import * as admin from 'firebase-admin';
export interface IImportOptions {
dates?: string[];
geos?: string[];
refs?: string[];
}
/**
* Convert time array in document object
* @param dateArray
* @param documentObj
* @param dateArray
* @param documentObj
*/
const updateTime = (dateArray, documentObj): void => {
dateArray.forEach(c => {
c.split(".").reduce((acc, cur, i, a) => {
c.split('.').reduce((acc, cur, i, a) => {
if (!a[i + 1] && acc[cur] && acc[cur]._seconds) {

@@ -23,9 +30,7 @@ acc[cur] = new Date(acc[cur]._seconds * 1000);

* @param {string} fileName
* @param {Array<string>} dateArray
* @param {Array<string>} geoArray
* @param {IImportOptions} options
*/
export const restore = (
fileName: string,
dateArray: Array<string>,
geoArray: Array<string>
options: IImportOptions
): Promise<any> => {

@@ -35,10 +40,10 @@ const db = admin.firestore();

return new Promise((resolve, reject) => {
if (typeof fileName === "object") {
if (typeof fileName === 'object') {
let dataArray = fileName;
updateCollection(db, dataArray, dateArray, geoArray)
updateCollection(db, dataArray, options)
.then(() => {
resolve({
status: true,
message: "Collection successfully imported!"
message: 'Collection successfully imported!'
});

@@ -50,3 +55,3 @@ })

} else {
fs.readFile(fileName, "utf8", function(err, data) {
fs.readFile(fileName, 'utf8', function(err, data) {
if (err) {

@@ -60,7 +65,7 @@ console.log(err);

updateCollection(db, dataArray, dateArray, geoArray)
updateCollection(db, dataArray, options)
.then(() => {
resolve({
status: true,
message: "Collection successfully imported!"
message: 'Collection successfully imported!'
});

@@ -73,3 +78,3 @@ })

}
});
}).catch(error => console.error(error));
};

@@ -88,4 +93,3 @@

dataArray: Array<any>,
dateArray: Array<string>,
geoArray: Array<string>
options: IImportOptions = {}
) => {

@@ -96,14 +100,16 @@ for (var index in dataArray) {

if (dataArray[index].hasOwnProperty(doc)) {
if (dataArray[index][doc]["subCollection"]) {
const subCollections = dataArray[index][doc]["subCollection"];
delete dataArray[index][doc]["subCollection"];
// asign document id for array type
let docId = Array.isArray(dataArray[index]) ? uuidv1() : doc;
if (dataArray[index][doc]['subCollection']) {
const subCollections = dataArray[index][docId]['subCollection'];
delete dataArray[index][doc]['subCollection'];
await startUpdating(
db,
collectionName,
doc,
docId,
dataArray[index][doc],
dateArray,
geoArray
options
);
await updateCollection(db, subCollections, [], []);
// Update sub collection
await updateCollection(db, subCollections);
} else {

@@ -113,6 +119,5 @@ await startUpdating(

collectionName,
doc,
docId,
dataArray[index][doc],
dateArray,
geoArray
options
);

@@ -129,3 +134,3 @@ }

* @param collectionName
* @param doc
* @param docId
* @param data

@@ -135,19 +140,27 @@ * @param dateArray

*/
const startUpdating = (
db,
collectionName: string,
doc: string,
docId: string,
data: object,
dateArray: Array<string>,
geoArray: Array<string>
options: IImportOptions
) => {
let parameterValid = true;
// Update date value
if (options.dates && options.dates.length > 0) {
updateTime(options.dates, data);
}
if (typeof dateArray === "object" && dateArray.length > 0) {
updateTime(dateArray, data);
// reference key
if (options.refs && options.refs.length > 0) {
options.refs.forEach(ref => {
if (data.hasOwnProperty(ref)) {
data[ref] = db.doc(data[ref]);
}
});
}
// Enter geo value
if (typeof geoArray !== "undefined" && geoArray.length > 0) {
geoArray.forEach(geo => {
if (options.geos && options.geos.length > 0) {
options.geos.forEach(geo => {
if (data.hasOwnProperty(geo)) {

@@ -159,4 +172,3 @@ data[geo] = new admin.firestore.GeoPoint(

} else {
console.log("Please check your geo parameters!!!", geoArray);
parameterValid = false;
console.warn('Please check your geo parameters!!!', options.geos);
}

@@ -166,21 +178,21 @@ });

if (parameterValid) {
return new Promise(resolve => {
db.collection(collectionName)
.doc(doc)
.set(data)
.then(() => {
console.log(`${doc} was successfully added to firestore!`);
resolve("Data written!");
})
.catch(error => {
console.log(error);
return new Promise((resolve, reject) => {
db.collection(collectionName)
.doc(docId)
.set(data)
.then(() => {
console.log(`${docId} was successfully added to firestore!`);
resolve({
status: true,
message: `${docId} was successfully added to firestore!`
});
});
} else {
console.log(
`${doc} was not imported to firestore. Please check your parameters or ignore if you don't need to import the property above.`
);
return false;
}
})
.catch(error => {
console.log(error);
reject({
status: false,
message: error.message
});
});
});
};

@@ -12,7 +12,9 @@ import * as admin from 'firebase-admin';

export const initializeApp = (serviceAccount: string, databaseURL: string) => {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
admin.firestore().settings({ timestampsInSnapshots: true });
if (admin.apps.length === 0) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
admin.firestore().settings({ timestampsInSnapshots: true });
}
return true;

@@ -36,11 +38,9 @@ };

* @param fileName
* @param dateArray
* @param geoArray
* @param options
*/
export const restore = (
fileName: string,
dateArray: Array<string> = [],
geoArray: Array<string> = []
options: restoreService.IImportOptions = {}
) => {
return restoreService.restore(fileName, dateArray, geoArray);
return restoreService.restore(fileName, options);
};

@@ -47,0 +47,0 @@

@@ -18,12 +18,9 @@ import { expect } from 'chai';

it('Get a colection with sub-collection', async () => {
try {
const data = await firestoreService.backup('test');
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('Restore data from API', async () => {
const backupData = await request(backupAPI);
const status = await firestoreService.restore(JSON.parse(backupData), {
dates: ['date'],
geos: ['location']
});
expect(status.status).ok;
});

@@ -45,7 +42,10 @@

it('Restore data', async () => {
it('Restore data with document id', async () => {
let status = await firestoreService.restore(
'test/import-to-firestore.json',
['date', 'schedule.time', 'three.level.time'],
['location']
{
dates: ['date', 'schedule.time', 'three.level.time'],
geos: ['location'],
refs: ['secondRef']
}
);

@@ -55,12 +55,16 @@ 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);
expect(typeof result.test['first-key'].secondRef).is.equal('object');
expect(
result.test['first-key'].subCollection['test/first-key/details'][
'33J2A10u5902CXagoBP6'
].dogName
).is.equal('hello');
});
it('Restore data from API', async () => {
const backupData = await request(backupAPI);
const status = await firestoreService.restore(
JSON.parse(backupData),
['date'],
['location']
it('Restore data as an array without document id', async () => {
let status = await firestoreService.restore(
'test/import-array-to-firestore.json'
);

@@ -70,2 +74,14 @@ expect(status.status).ok;

it('Get a colection with sub-collection', async () => {
try {
const data = await firestoreService.backup('test');
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 one collection', async () => {

@@ -72,0 +88,0 @@ const result = await firestoreService.backup('test');

@@ -32,2 +32,3 @@ {

"email": "dungnq@itbox4vn.com",
"secondRef": "test/second-key",
"subCollection": {

@@ -34,0 +35,0 @@ "test/first-key/details": {

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