-
Notifications
You must be signed in to change notification settings - Fork 4
/
Deserialize.ts
100 lines (88 loc) · 3.45 KB
/
Deserialize.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import firebase from "firebase";
import {SimpleJsonType} from "./types";
import {mapDeepWithArrays, UnmappedData} from "./map-deep-with-arrays";
import { get, isEqual, omit } from "lodash";
function objectifyDocumentProperty(
item: string,
firestore: firebase.firestore.Firestore,
geoPoint: typeof firebase.firestore.GeoPoint,
timestamp: typeof firebase.firestore.Timestamp,
): any {
let modifiedItem: any = item;
if(item.startsWith && typeof item === 'string') {
if(item.startsWith('__DocumentReference__')) {
const path = item.split('__DocumentReference__')[1];
modifiedItem = firestore.doc(path);
}
if(item.startsWith('__Timestamp__')) {
const dateString = item.split('__Timestamp__')[1];
modifiedItem = timestamp.fromDate(new Date(dateString));
}
if(item.startsWith('__GeoPoint__')) {
const geoSection = item.split('__GeoPoint__')[1];
const [latitude, longitude] = geoSection.split('###');
modifiedItem = new geoPoint(parseFloat(latitude), parseFloat(longitude));
}
}
return modifiedItem;
}
function metadataIsEqual(metadata: firebase.firestore.SnapshotMetadata): boolean {
return metadata.fromCache && !metadata.hasPendingWrites;
}
function documentIsEqual(id: string, docA: UnmappedData, docB: firebase.firestore.DocumentSnapshot): boolean {
return isEqual(docA, docB.data()) && id === docB.id;
}
function getField(mappedObject: UnmappedData, fieldPath: string) {
return get(mappedObject, fieldPath);
}
function objectifyDocument(
partialObject: {
[key: string]: SimpleJsonType,
},
firestore: firebase.firestore.Firestore,
geoPoint: typeof firebase.firestore.GeoPoint,
timestamp: typeof firebase.firestore.Timestamp,
): firebase.firestore.DocumentSnapshot {
const mappedObject = mapDeepWithArrays(partialObject, (item: string) => {
return objectifyDocumentProperty(item, firestore, geoPoint, timestamp);
});
const id = partialObject.__id__ as string;
const path = partialObject.__path__ as string;
const mappedObjectToInclude = omit(mappedObject, '__id__', '__path__');
return {
exists: true,
id,
metadata: {
hasPendingWrites: false,
fromCache: true,
isEqual: metadataIsEqual
},
get: (fieldPath: string) => {
return getField(mappedObjectToInclude, fieldPath);
},
ref: firebase.firestore().doc(path),
isEqual(other: firebase.firestore.DocumentSnapshot): boolean {
return documentIsEqual(id, mappedObjectToInclude, other);
},
data: () => mappedObjectToInclude
};
}
export function deserializeDocumentSnapshotArray(
string: string,
firestore: firebase.firestore.Firestore,
geoPoint: typeof firebase.firestore.GeoPoint,
timestamp: typeof firebase.firestore.Timestamp,
): firebase.firestore.DocumentSnapshot[] {
const parsedString: any[] = JSON.parse(string);
return parsedString.map(doc => {
return objectifyDocument(doc, firestore, geoPoint, timestamp);
});
}
export function deserializeDocumentSnapshot(
string: string,
firestore: firebase.firestore.Firestore,
geoPoint: typeof firebase.firestore.GeoPoint,
timestamp: typeof firebase.firestore.Timestamp,
): firebase.firestore.DocumentSnapshot {
return objectifyDocument(JSON.parse(string), firestore, geoPoint, timestamp);
}