Passed
Push — master ( b73752...5ddec9 )
by Miloš
02:58
created

FirestoreStorage.updateStoredDataByFirebaseUser   A

Complexity

Conditions 2

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 16
rs 9.7
c 0
b 0
f 0
cc 2
1
import { Injectable } from "@angular/core";
2
import { AngularFireAuth } from "@angular/fire/auth";
3
import {
4
    AngularFirestore,
5
    AngularFirestoreDocument,
6
} from "@angular/fire/firestore";
7
import * as firebase from "firebase";
8
import { Observable, of } from "rxjs";
9
import { switchMap } from "rxjs/operators";
10
import { UniFirebaseLoginConfig } from "../config/uni-firebase-login-config";
11
import { StorageUserModel } from "../model/storage-user-model";
12
import { UserModel } from "../model/user-model";
13
import { IStorageProvider } from "./i-storage-provider";
14
15
@Injectable({
16
    providedIn: "root",
17
})
18
export class FirestoreStorage<User extends UserModel = UserModel>
19
    implements IStorageProvider<User> {
20
    public constructor(
21
        protected angularFireAuth: AngularFireAuth,
22
        protected angularFirestore: AngularFirestore,
23
        protected config: UniFirebaseLoginConfig,
24
    ) {}
25
26
    public async updateStoredDataByUser(user: User): Promise<void> {
27
        if (user.uid) {
28
            const userRef = this.getUserRef(user.uid);
29
30
            const data = this.config.storageUserFactoryFunc(
31
                this.config.mapUserToStorageFunc(user),
32
            );
33
34
            await userRef.set(JSON.parse(JSON.stringify(data)), {
35
                merge: true,
36
            });
37
        } else {
38
            throw new Error("Firebase user has no UID.");
39
        }
40
    }
41
42
    public getUserRef(
43
        userUid: string,
44
    ): AngularFirestoreDocument<StorageUserModel> {
45
        if (this.config.storageUserTable === null) {
46
            throw new Error("userTable is not specified!");
47
        }
48
49
        return this.angularFirestore
50
            .collection(this.config.storageUserTable)
51
            .doc(userUid);
52
    }
53
54
    public async updateStoredDataByFirebaseUser(
55
        firebaseUser: firebase.User,
56
    ): Promise<void> {
57
        if (firebaseUser.uid) {
58
            const userRef = this.getUserRef(firebaseUser.uid);
59
60
            const data = this.config.storageUserFactoryFunc(
61
                this.config.mapFirebaseUserToStorageFunc(firebaseUser),
62
            );
63
64
            await userRef.set(JSON.parse(JSON.stringify(data)), {
65
                merge: true,
66
            });
67
        } else {
68
            throw new Error("Firebase user has no UID.");
69
        }
70
    }
71
72
    public async fetchUser(): Promise<User | null> {
73
        return this.subscribeUser().toPromise();
74
    }
75
76
    public subscribeUser(): Observable<User | null> {
77
        // Get the auth state, then fetch the Firestore user document or return null
78
        return this.angularFireAuth.authState.pipe(
79
            switchMap((user: any) => {
80
                if (user) {
81
                    // User is logged in
82
                    return this.angularFirestore
83
                        .doc<StorageUserModel>(
84
                            `${this.config.storageUserTable}/${user.uid}`,
85
                        )
86
                        .valueChanges()
87
                        .pipe(
88
                            switchMap((userFirebase: any) => {
89
                                return new Observable(subscriber => {
90
                                    subscriber.next(
91
                                        Object.assign<User, any>(
92
                                            this.getNewUser(),
93
                                            userFirebase,
94
                                        ),
95
                                    );
96
                                    subscriber.complete();
97
                                });
98
                            }),
99
                        );
100
                }
101
                // Logged out
102
                return of(null);
103
            }),
104
        ) as Observable<User | null>;
105
    }
106
107
    /**
108
     * Override this method if you want to use custom model class
109
     */
110
    protected getNewUser(): User {
111
        return this.config.userFactoryFunc() as User;
112
    }
113
}
114