Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit da2fef3

Browse files
Merge pull request #807 from deckgo/clean-firestore-delete
feat: recursively clean Firestore FieldValue.delete
2 parents 5540cd2 + a712977 commit da2fef3

File tree

6 files changed

+36
-22
lines changed

6 files changed

+36
-22
lines changed

studio/src/app/services/data/deck/deck.offline.service.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {get, set} from 'idb-keyval';
33
import {Deck} from '../../../models/data/deck';
44

55
import {OfflineUtils} from '../../../utils/editor/offline.utils';
6+
import {FirestoreUtils} from '../../../utils/editor/firestore.utils';
67

78
export class DeckOfflineService {
89
private static instance: DeckOfflineService;
@@ -41,7 +42,7 @@ export class DeckOfflineService {
4142
// @ts-ignore
4243
deck.data.updated_at = new Date();
4344

44-
if (deck.data.background && OfflineUtils.shouldAttributeBeCleaned(deck.data.background)) {
45+
if (deck.data.background && FirestoreUtils.shouldAttributeBeCleaned(deck.data.background)) {
4546
deck.data.background = null;
4647
}
4748

studio/src/app/services/data/deck/deck.online.service.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as firebase from 'firebase/app';
22
import 'firebase/firestore';
33

44
import {Deck, DeckData} from '../../../models/data/deck';
5+
import {FirestoreUtils} from '../../../utils/editor/firestore.utils';
56

67
export class DeckOnlineService {
78
private static instance: DeckOnlineService;
@@ -51,10 +52,7 @@ export class DeckOnlineService {
5152
try {
5253
await firestore.collection('decks').doc(deck.id).set(deck.data, {merge: true});
5354

54-
// Fetch newly persisted deck (clean firebase.firestore.FieldValue.delete())
55-
const updatedDeck: Deck = await this.get(deck.id);
56-
57-
resolve(updatedDeck);
55+
resolve(FirestoreUtils.filterDelete(deck));
5856
} catch (err) {
5957
reject(err);
6058
}

studio/src/app/services/data/slide/slide.offline.service.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {del, get, set} from 'idb-keyval';
55
import {Slide, SlideData} from '../../../models/data/slide';
66

77
import {OfflineUtils} from '../../../utils/editor/offline.utils';
8+
import {FirestoreUtils} from '../../../utils/editor/firestore.utils';
89

910
export class SlideOfflineService {
1011
private static instance: SlideOfflineService;
@@ -27,7 +28,7 @@ export class SlideOfflineService {
2728

2829
const slide: Slide = {
2930
id: slideId,
30-
data: slideData
31+
data: slideData,
3132
};
3233

3334
const now: Date = new Date();
@@ -68,7 +69,7 @@ export class SlideOfflineService {
6869

6970
slide.data.attributes = await OfflineUtils.cleanAttributes(slide.data.attributes);
7071

71-
if (slide.data.content && OfflineUtils.shouldAttributeBeCleaned(slide.data.content)) {
72+
if (slide.data.content && FirestoreUtils.shouldAttributeBeCleaned(slide.data.content)) {
7273
slide.data.content = null;
7374
}
7475

studio/src/app/services/editor/offline/offline.service.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {Slide} from '../../../models/data/slide';
1111
import {SlotType} from '../../../utils/editor/slot-type';
1212

1313
import {OfflineUtils} from '../../../utils/editor/offline.utils';
14+
import {FirestoreUtils} from '../../../utils/editor/firestore.utils';
1415
import {ServiceWorkerUtils} from '../../../utils/core/service-worker-utils';
1516

1617
import {SlideOnlineService} from '../../data/slide/slide.online.service';
@@ -352,7 +353,7 @@ export class OfflineService {
352353

353354
await this.saveSlides(deckStore.state.deck);
354355

355-
if (deckStore.state.deck.data.background && OfflineUtils.shouldAttributeBeCleaned(deckStore.state.deck.data.background)) {
356+
if (deckStore.state.deck.data.background && FirestoreUtils.shouldAttributeBeCleaned(deckStore.state.deck.data.background)) {
356357
deckStore.state.deck.data.background = null;
357358
}
358359

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export class FirestoreUtils {
2+
static filterDelete<T>(obj: T): T {
3+
if (typeof obj !== 'object' || Array.isArray(obj)) {
4+
return obj;
5+
}
6+
7+
return Object.keys(obj)
8+
.filter((key) => !this.shouldAttributeBeCleaned(obj[key]))
9+
.reduce((res, key) => ((res[key] = this.filterDelete(obj[key])), res), {} as T);
10+
}
11+
12+
static shouldAttributeBeCleaned<T>(attr: T): boolean {
13+
// If attr is a not an object (string, number or boolean) for sure it isn't a Firestore FieldValue.delete
14+
if (typeof attr !== 'object' || Array.isArray(attr)) {
15+
return false;
16+
}
17+
18+
const firestoreDelete = Object.keys(attr).find((key: string) => {
19+
return attr[key] === 'FieldValue.delete';
20+
});
21+
22+
return firestoreDelete !== null && firestoreDelete !== undefined;
23+
}
24+
}

studio/src/app/utils/editor/offline.utils.tsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import * as firebase from 'firebase/app';
33
import {SlideAttributes} from '../../models/data/slide';
44
import {DeckAttributes} from '../../models/data/deck';
55

6+
import {FirestoreUtils} from './firestore.utils';
7+
68
export class OfflineUtils {
79
static cleanAttributes(attributes: SlideAttributes | DeckAttributes): Promise<SlideAttributes | DeckAttributes> {
810
return new Promise<SlideAttributes | DeckAttributes>((resolve) => {
@@ -22,7 +24,7 @@ export class OfflineUtils {
2224
const attr = attributes[key];
2325

2426
// Replace Firestore "to delete fields" with null values
25-
if (this.shouldAttributeBeCleaned(attr)) {
27+
if (FirestoreUtils.shouldAttributeBeCleaned(attr)) {
2628
attributes[key] = null;
2729
}
2830
});
@@ -31,19 +33,6 @@ export class OfflineUtils {
3133
});
3234
}
3335

34-
static shouldAttributeBeCleaned(attr): boolean {
35-
// If attr is a not an object (string, number or boolean) for sure it isn't a Firestore FieldValue.delete
36-
if (typeof attr !== 'object') {
37-
return false;
38-
}
39-
40-
const firestoreDelete = Object.keys(attr).find((key: string) => {
41-
return attr[key] === 'FieldValue.delete';
42-
});
43-
44-
return firestoreDelete !== null;
45-
}
46-
4736
static prepareAttributes(attributes: SlideAttributes | DeckAttributes): Promise<SlideAttributes | DeckAttributes> {
4837
return new Promise<SlideAttributes | DeckAttributes>((resolve) => {
4938
if (!attributes) {

0 commit comments

Comments
 (0)