Skip to content

Commit 799d1c5

Browse files
authored
Merge pull request #71 from ShoeBoom/master
added method to clear all firestore data
2 parents de23c0f + bcb3519 commit 799d1c5

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ lib
44
.npmrc
55
.vscode
66
*.tgz
7-
.tmp
7+
.tmp
8+
*.log

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"pretest": "node_modules/.bin/tsc",
1212
"test": "mocha .tmp/spec/index.spec.js",
1313
"posttest": "npm run lint && rm -rf .tmp",
14+
"preintegrationTest": "node_modules/.bin/tsc",
15+
"integrationTest": "firebase emulators:exec --project=not-a-project --only firestore 'mocha .tmp/spec/integration/**/*.spec.js'",
16+
"postintegrationTest": "rm -rf .tmp",
1417
"format": "prettier --check '**/*.{json,ts,yml,yaml}'",
1518
"format:fix": "prettier --write '**/*.{json,ts,yml,yaml}'"
1619
},
@@ -44,6 +47,7 @@
4447
"chai": "^4.2.0",
4548
"firebase-admin": "~8.9.0",
4649
"firebase-functions": "^3.3.0",
50+
"firebase-tools": "^8.9.2",
4751
"mocha": "^6.2.2",
4852
"prettier": "^1.19.1",
4953
"sinon": "^7.5.0",
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { expect } from 'chai';
2+
import { firestore, initializeApp } from 'firebase-admin';
3+
import fft = require('../../../src/index');
4+
5+
describe('providers/firestore', () => {
6+
before(() => {
7+
initializeApp();
8+
});
9+
10+
it('clears database with clearFirestoreData', async () => {
11+
const test = fft({ projectId: 'not-a-project' });
12+
const db = firestore();
13+
14+
await Promise.all([
15+
db
16+
.collection('test')
17+
.doc('doc1')
18+
.set({}),
19+
db
20+
.collection('test')
21+
.doc('doc1')
22+
.collection('test')
23+
.doc('doc2')
24+
.set({}),
25+
]);
26+
27+
await test.firestore.clearFirestoreData({ projectId: 'not-a-project' });
28+
29+
const docs = await Promise.all([
30+
db
31+
.collection('test')
32+
.doc('doc1')
33+
.get(),
34+
db
35+
.collection('test')
36+
.doc('doc1')
37+
.collection('test')
38+
.doc('doc2')
39+
.get(),
40+
]);
41+
expect(docs[0].exists).to.be.false;
42+
expect(docs[1].exists).to.be.false;
43+
});
44+
});

src/providers/firestore.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { has, get, isEmpty, isPlainObject, mapValues } from 'lodash';
2727

2828
import { testApp } from '../app';
2929

30+
import * as http from 'http';
31+
3032
/** Optional parameters for creating a DocumentSnapshot. */
3133
export interface DocumentSnapshotOptions {
3234
/** ISO timestamp string for the snapshot was read, default is current time. */
@@ -214,3 +216,58 @@ export function objectToValueProto(data: object) {
214216

215217
return mapValues(data, encodeHelper);
216218
}
219+
220+
const FIRESTORE_ADDRESS_ENVS = [
221+
'FIRESTORE_EMULATOR_HOST',
222+
'FIREBASE_FIRESTORE_EMULATOR_ADDRESS',
223+
];
224+
225+
const FIRESTORE_ADDRESS = FIRESTORE_ADDRESS_ENVS.reduce(
226+
(addr, name) => process.env[name] || addr,
227+
'localhost:8080'
228+
);
229+
const FIRESTORE_PORT = FIRESTORE_ADDRESS.split(':')[1];
230+
231+
/** Clears all data in firestore. Works only in offline mode.
232+
*/
233+
export function clearFirestoreData(options: { projectId: string } | string) {
234+
return new Promise((resolve, reject) => {
235+
let projectId;
236+
237+
if (typeof options === 'string') {
238+
projectId = options;
239+
} else if (typeof options === 'object' && has(options, 'projectId')) {
240+
projectId = options.projectId;
241+
} else {
242+
throw new Error('projectId not specified');
243+
}
244+
245+
const config = {
246+
method: 'DELETE',
247+
hostname: 'localhost',
248+
port: FIRESTORE_PORT,
249+
path: `/emulator/v1/projects/${projectId}/databases/(default)/documents`,
250+
};
251+
252+
const req = http.request(config, (res) => {
253+
if (res.statusCode !== 200) {
254+
reject(new Error(`statusCode: ${res.statusCode}`));
255+
}
256+
res.on('data', () => {});
257+
res.on('end', resolve);
258+
});
259+
260+
req.on('error', (error) => {
261+
reject(error);
262+
});
263+
264+
const postData = JSON.stringify({
265+
database: `projects/${projectId}/databases/(default)`,
266+
});
267+
268+
req.setHeader('Content-Length', postData.length);
269+
270+
req.write(postData);
271+
req.end();
272+
});
273+
}

0 commit comments

Comments
 (0)