Skip to content

Commit 46539f1

Browse files
committed
Merge branch 'master' of https://github.com/nathan815/react-admin-firebase into nathan815-master
2 parents dad04f6 + 2839e23 commit 46539f1

22 files changed

+204
-604
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ const options = {
112112
firestoreCostsLogger: {
113113
enabled: false,
114114
localStoragePrefix // optional
115-
}
115+
},
116+
// Function to transform documents before they are written to Firestore
117+
transformToDb: (resourceName, document, documentId) => document
116118
}
117119

118120
const dataProvider = FirebaseDataProvider(config, options);

package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
"rxjs": "^6.5.x"
1616
},
1717
"devDependencies": {
18-
"@firebase/testing": "^0.20.11",
19-
"@types/firebase": "^3.2.1",
18+
"@firebase/rules-unit-testing": "^2.0.2",
2019
"@types/jest": "^24.0.13",
2120
"@types/lodash": "^4.14.150",
2221
"@types/node": "^10.9.4",
@@ -25,13 +24,13 @@
2524
"@types/rx": "^4.1.1",
2625
"cpx": "^1.5.0",
2726
"del": "^3.0.0",
28-
"ra-core": "3.10.0",
2927
"firebase": "^9.6.4",
3028
"firebase-tools": "^8.1.1",
3129
"gulp": "^3.9.1",
3230
"gulp-sequence": "^1.0.0",
3331
"jest": "^23.6.0",
3432
"microbundle": "^0.12.4",
33+
"ra-core": "3.10.0",
3534
"ts-jest": "^25",
3635
"tslint": "^5.16.0",
3736
"typescript": "4.5.5"

src/providers/commands/Create.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ export async function Create<T extends ra.Record>(
2828
client.checkRemoveIdField(docObj, overridenId);
2929
await client.addCreatedByFields(docObj);
3030
await client.addUpdatedByFields(docObj);
31+
const docObjTransformed = client.transformToDb(resourceName, docObj, overridenId);
3132
log("Create", { docObj });
32-
await r.collection.doc(overridenId).set(docObj, { merge: false });
33+
await r.collection.doc(overridenId).set(docObjTransformed, { merge: false });
3334
return {
3435
data: {
35-
...data,
36+
...docObjTransformed,
3637
id: overridenId,
3738
},
3839
};
@@ -43,10 +44,11 @@ export async function Create<T extends ra.Record>(
4344
client.checkRemoveIdField(docObj, newId);
4445
await client.addCreatedByFields(docObj);
4546
await client.addUpdatedByFields(docObj);
46-
await r.collection.doc(newId).set(docObj, { merge: false });
47+
const docObjTransformed = client.transformToDb(resourceName, docObj, newId);
48+
await r.collection.doc(newId).set(docObjTransformed, { merge: false });
4749
return {
4850
data: {
49-
...data,
51+
...docObjTransformed,
5052
id: newId,
5153
},
5254
};

src/providers/commands/Update.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export async function Update<T extends ra.Record>(
1717
const docObj = { ...data };
1818
client.checkRemoveIdField(docObj, id);
1919
await client.addUpdatedByFields(docObj);
20-
await r.collection.doc(id).update(docObj);
20+
const docObjTransformed = client.transformToDb(resourceName, docObj, id);
21+
await r.collection.doc(id).update(docObjTransformed);
2122
return {
2223
data: {
2324
...data,

src/providers/commands/UpdateMany.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ export async function UpdateMany(
2020
const docObj = { ...data };
2121
client.checkRemoveIdField(docObj, idStr);
2222
await client.addUpdatedByFields(docObj);
23+
const docObjTransformed = client.transformToDb(resourceName, docObj, idStr);
2324
await r.collection
2425
.doc(idStr)
25-
.update(docObj);
26+
.update(docObjTransformed);
2627
return {
2728
...data,
2829
id: idStr

src/providers/database/FireClient.ts

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ export class FireClient {
3131
}
3232
}
3333

34+
public transformToDb(resourceName: string, document: any, docId: string): any {
35+
if (typeof this.options.transformToDb === 'function') {
36+
return this.options.transformToDb(resourceName, document, docId);
37+
}
38+
return document;
39+
}
40+
3441
public async parseDataAndUpload(r: IResource, id: string, data: any) {
3542
if (!data) {
3643
return data;

src/providers/options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export interface RAFirebaseOptions {
4747
enabled: boolean;
4848
persistCount?: boolean;
4949
};
50+
// Function to transform documents before they are written to Firestore
51+
transformToDb?: (resourceName: string, document: any, documentId: string) => any;
5052
/* OLD FLAGS */
5153
/**
5254
* @deprecated The method should not be used

tests/integration-tests/ApiCreate.spec.ts

+38-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Create } from "../../src/providers/commands";
33

44
describe("ApiCreate", () => {
55
test("FireClient create doc", async () => {
6-
const client = MakeMockClient({
6+
const client = await MakeMockClient({
77
logging: true,
88
disableMeta: true,
99
});
@@ -15,7 +15,7 @@ describe("ApiCreate", () => {
1515
expect(first.name).toBe("John");
1616
}, 100000);
1717
test("FireClient create doc with custom meta", async () => {
18-
const client = MakeMockClient({
18+
const client = await MakeMockClient({
1919
logging: true,
2020
renameMetaFields: {
2121
updated_by: 'MY_CREATED_BY',
@@ -28,4 +28,40 @@ describe("ApiCreate", () => {
2828

2929
expect(first.hasOwnProperty('MY_CREATED_BY')).toBeTruthy();
3030
}, 100000);
31+
test("FireClient create doc with transformToDb function provided", async () => {
32+
const client = await MakeMockClient({
33+
logging: true,
34+
transformToDb: (resourceName, document, id) => {
35+
if (resourceName === "users") {
36+
return {
37+
...document,
38+
firstName: document.firstName.toUpperCase(),
39+
picture: document.picture.src || document.picture,
40+
};
41+
}
42+
return document;
43+
}
44+
});
45+
46+
const newUser = {
47+
firstName: "John",
48+
lastName: "Last",
49+
age: 20,
50+
picture: {
51+
src: "http://example.com/pic.png"
52+
},
53+
};
54+
55+
await Create("users", { data: newUser }, client);
56+
const users = (await client.fireWrapper.dbGetCollection("users").get()).docs;
57+
58+
expect(users.length).toBe(1);
59+
expect(users[0].data()).toMatchObject({
60+
firstName: "JOHN",
61+
lastName: "Last",
62+
age: 20,
63+
picture: "http://example.com/pic.png",
64+
});
65+
66+
}, 100000);
3167
});

tests/integration-tests/ApiDelete.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Delete } from "../../src/providers/commands";
33

44
describe("api methods", () => {
55
test("FireClient delete doc", async () => {
6-
const client = MakeMockClient();
6+
const client = await MakeMockClient();
77

88
const docId = "test123";
99
const docObj = { id: docId, name: "Jim" };

tests/integration-tests/ApiDeleteMany.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DeleteMany } from "../../src/providers/commands";
33

44
describe("api methods", () => {
55
test("FireClient delete doc", async () => {
6-
const client = MakeMockClient();
6+
const client = await MakeMockClient();
77
const docIds = ["test123", "test22222", "asdads"];
88
const collName = "deleteables";
99
const collection = client.fireWrapper.dbGetCollection(collName);

tests/integration-tests/ApiGetList.spec.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { FireStoreCollectionRef } from "../../src/misc/firebase-models";
44

55
describe("api methods", () => {
66
test("FireClient list docs", async () => {
7-
const client = MakeMockClient();
7+
const client = await MakeMockClient();
88
const docIds = ["test123", "test22222", "asdads"];
99
const collName = "list-mes";
1010
const collection = client.fireWrapper.dbGetCollection(collName);
@@ -31,7 +31,7 @@ describe("api methods", () => {
3131
}, 100000);
3232

3333
test("FireClient list docs with boolean filter", async () => {
34-
const client = MakeMockClient();
34+
const client = await MakeMockClient();
3535
const testDocs = [
3636
{
3737
title: "A",
@@ -71,7 +71,7 @@ describe("api methods", () => {
7171
}, 100000);
7272

7373
test("FireClient list docs with dotpath sort", async () => {
74-
const client = MakeMockClient();
74+
const client = await MakeMockClient();
7575
const testDocs = [
7676
{
7777
obj: {
@@ -117,7 +117,7 @@ describe("api methods", () => {
117117
}, 100000);
118118

119119
test("FireClient with filter gte", async () => {
120-
const client = MakeMockClient();
120+
const client = await MakeMockClient();
121121
const testDocs = [
122122
{
123123
title: "A",

tests/integration-tests/ApiGetMany.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { GetMany } from "../../src/providers/queries";
33

44
describe("api methods", () => {
55
test("FireClient list docs", async () => {
6-
const client = MakeMockClient();
6+
const client = await MakeMockClient();
77
const docIds = ["test123", "test22222", "asdads"];
88
const collName = "list-mes";
99
const collection = client.fireWrapper.dbGetCollection(collName);

tests/integration-tests/ApiGetOne.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { GetOne } from "../../src/providers/queries";
33

44
describe("api methods", () => {
55
test("FireClient apiGetOne", async () => {
6-
const client = MakeMockClient();
6+
const client = await MakeMockClient();
77
const docIds = ["test123", "test22222", "asdads"];
88
const collName = "list-mes";
99
const collection = client.fireWrapper.dbGetCollection(collName);
@@ -18,7 +18,7 @@ describe("api methods", () => {
1818
}, 100000);
1919

2020
test("FireClient apiGetOne, with nested Dates", async () => {
21-
const client = MakeMockClient();
21+
const client = await MakeMockClient();
2222
const collName = "list-mes";
2323
const docId = "1234";
2424
const collection = client.fireWrapper.dbGetCollection(collName);

tests/integration-tests/ApiRootRef.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { MakeMockClient } from "./utils/test-helpers";
22

33
describe("ApiRootRef", () => {
44
test("rootref1", async () => {
5-
const client = MakeMockClient({ rootRef: "root-ref1/ok" });
5+
const client = await MakeMockClient({ rootRef: "root-ref1/ok" });
66
const rm = client.rm;
77
const docRef = await client
88
.fireWrapper
@@ -15,7 +15,7 @@ describe("ApiRootRef", () => {
1515
}, 10000);
1616

1717
test("rootreffunction1", async () => {
18-
const client = MakeMockClient({ rootRef: "root-ref-function1/ok" });
18+
const client = await MakeMockClient({ rootRef: "root-ref-function1/ok" });
1919
const rm = client.rm;
2020
const docRef = await client
2121
.fireWrapper

tests/integration-tests/ApiSoftDelete.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DeleteSoft } from "../../src/providers/commands";
33

44
describe("api methods", () => {
55
test("FireClient delete doc", async () => {
6-
const client = MakeMockClient({ softDelete: true, disableMeta: true });
6+
const client = await MakeMockClient({ softDelete: true, disableMeta: true });
77
const id = "test123";
88
const collName = "t2";
99
const docRef = client.fireWrapper.dbGetCollection(collName).doc(id);

tests/integration-tests/ApiSoftDeleteMany.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DeleteManySoft } from "../../src/providers/commands";
33

44
describe("api methods", () => {
55
test("FireClient delete doc", async () => {
6-
const client = MakeMockClient({ softDelete: true, disableMeta: true });
6+
const client = await MakeMockClient({ softDelete: true, disableMeta: true });
77
const docIds = ["test123", "test22222", "asdads"];
88
const collName = "deleteables";
99
const collection = client.fireWrapper.dbGetCollection(collName);

tests/integration-tests/ApiUpdate.spec.ts

+46-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Update } from "../../src/providers/commands";
33

44
describe("api methods", () => {
55
test("FireClient update doc", async () => {
6-
const client = MakeMockClient({ disableMeta: true });
6+
const client = await MakeMockClient({ disableMeta: true });
77
const id = "testsss123";
88
const collName = "t2";
99
const docRef = client.fireWrapper.dbGetCollection(collName).doc(id);
@@ -23,4 +23,49 @@ describe("api methods", () => {
2323
expect(res.exists).toBeTruthy();
2424
expect(res.get("title")).toBe("asd");
2525
}, 100000);
26+
27+
test("FireClient update doc with transformToDb function provided", async () => {
28+
const client = await MakeMockClient({
29+
transformToDb: (resourceName, document, id) => {
30+
if (resourceName === "users") {
31+
return {
32+
...document,
33+
firstName: document.firstName.toUpperCase(),
34+
};
35+
}
36+
return document;
37+
}
38+
});
39+
40+
const id = "user123";
41+
const docRef = client.fireWrapper.dbGetCollection("users").doc(id);
42+
await docRef.set({ name: "Jim" });
43+
44+
const previousUser = {
45+
id,
46+
firstName: "Bob",
47+
lastName: "Last",
48+
};
49+
const user = {
50+
...previousUser,
51+
firstName: "John",
52+
};
53+
54+
await Update(
55+
"users",
56+
{
57+
id: id,
58+
data: user,
59+
previousData: previousUser,
60+
},
61+
client
62+
);
63+
64+
const res = await docRef.get();
65+
expect(res.exists).toBeTruthy();
66+
expect(res.data()).toMatchObject({
67+
firstName: "JOHN",
68+
lastName: "Last",
69+
});
70+
}, 100000);
2671
});

0 commit comments

Comments
 (0)