@chem-po/firebase-native 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -0
- package/lib/commonjs/adapter/auth.js +431 -0
- package/lib/commonjs/adapter/auth.js.map +1 -0
- package/lib/commonjs/adapter/db.js +103 -0
- package/lib/commonjs/adapter/db.js.map +1 -0
- package/lib/commonjs/adapter/index.js +16 -0
- package/lib/commonjs/adapter/index.js.map +1 -0
- package/lib/commonjs/adapter/storage.js +52 -0
- package/lib/commonjs/adapter/storage.js.map +1 -0
- package/lib/commonjs/auth/functions.js +11 -0
- package/lib/commonjs/auth/functions.js.map +1 -0
- package/lib/commonjs/auth/index.js +17 -0
- package/lib/commonjs/auth/index.js.map +1 -0
- package/lib/commonjs/components/AuthenticatorVerify.js +90 -0
- package/lib/commonjs/components/AuthenticatorVerify.js.map +1 -0
- package/lib/commonjs/components/FirebaseSignIn.js +196 -0
- package/lib/commonjs/components/FirebaseSignIn.js.map +1 -0
- package/lib/commonjs/components/PhoneVerify.js +123 -0
- package/lib/commonjs/components/PhoneVerify.js.map +1 -0
- package/lib/commonjs/components/TwoFactorAuthModal.js +118 -0
- package/lib/commonjs/components/TwoFactorAuthModal.js.map +1 -0
- package/lib/commonjs/components/index.js +28 -0
- package/lib/commonjs/components/index.js.map +1 -0
- package/lib/commonjs/contexts/FirebaseContext.js +48 -0
- package/lib/commonjs/contexts/FirebaseContext.js.map +1 -0
- package/lib/commonjs/contexts/index.js +17 -0
- package/lib/commonjs/contexts/index.js.map +1 -0
- package/lib/commonjs/db/index.js +17 -0
- package/lib/commonjs/db/index.js.map +1 -0
- package/lib/commonjs/db/utils.js +120 -0
- package/lib/commonjs/db/utils.js.map +1 -0
- package/lib/commonjs/hooks/backend.js +12 -0
- package/lib/commonjs/hooks/backend.js.map +1 -0
- package/lib/commonjs/hooks/index.js +17 -0
- package/lib/commonjs/hooks/index.js.map +1 -0
- package/lib/commonjs/hooks/useAuthenticatorVerify.js +52 -0
- package/lib/commonjs/hooks/useAuthenticatorVerify.js.map +1 -0
- package/lib/commonjs/hooks/usePhoneVerify.js +83 -0
- package/lib/commonjs/hooks/usePhoneVerify.js.map +1 -0
- package/lib/commonjs/icons/Google.js +29 -0
- package/lib/commonjs/icons/Google.js.map +1 -0
- package/lib/commonjs/index.js +105 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/storage/index.js +17 -0
- package/lib/commonjs/storage/index.js.map +1 -0
- package/lib/commonjs/storage/utils.js +37 -0
- package/lib/commonjs/storage/utils.js.map +1 -0
- package/lib/commonjs/types/adapter.js +6 -0
- package/lib/commonjs/types/adapter.js.map +1 -0
- package/lib/commonjs/types/auth.js +6 -0
- package/lib/commonjs/types/auth.js.map +1 -0
- package/lib/commonjs/types/db.js +6 -0
- package/lib/commonjs/types/db.js.map +1 -0
- package/lib/commonjs/types/functions.js +6 -0
- package/lib/commonjs/types/functions.js.map +1 -0
- package/lib/commonjs/types/index.js +6 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/storage.js +6 -0
- package/lib/commonjs/types/storage.js.map +1 -0
- package/lib/commonjs/utils/validation.js +71 -0
- package/lib/commonjs/utils/validation.js.map +1 -0
- package/lib/module/adapter/auth.js +424 -0
- package/lib/module/adapter/auth.js.map +1 -0
- package/lib/module/adapter/db.js +96 -0
- package/lib/module/adapter/db.js.map +1 -0
- package/lib/module/adapter/index.js +9 -0
- package/lib/module/adapter/index.js.map +1 -0
- package/lib/module/adapter/storage.js +45 -0
- package/lib/module/adapter/storage.js.map +1 -0
- package/lib/module/auth/functions.js +3 -0
- package/lib/module/auth/functions.js.map +1 -0
- package/lib/module/auth/index.js +2 -0
- package/lib/module/auth/index.js.map +1 -0
- package/lib/module/components/AuthenticatorVerify.js +82 -0
- package/lib/module/components/AuthenticatorVerify.js.map +1 -0
- package/lib/module/components/FirebaseSignIn.js +187 -0
- package/lib/module/components/FirebaseSignIn.js.map +1 -0
- package/lib/module/components/PhoneVerify.js +116 -0
- package/lib/module/components/PhoneVerify.js.map +1 -0
- package/lib/module/components/TwoFactorAuthModal.js +110 -0
- package/lib/module/components/TwoFactorAuthModal.js.map +1 -0
- package/lib/module/components/index.js +3 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/contexts/FirebaseContext.js +39 -0
- package/lib/module/contexts/FirebaseContext.js.map +1 -0
- package/lib/module/contexts/index.js +2 -0
- package/lib/module/contexts/index.js.map +1 -0
- package/lib/module/db/index.js +2 -0
- package/lib/module/db/index.js.map +1 -0
- package/lib/module/db/utils.js +111 -0
- package/lib/module/db/utils.js.map +1 -0
- package/lib/module/hooks/backend.js +5 -0
- package/lib/module/hooks/backend.js.map +1 -0
- package/lib/module/hooks/index.js +2 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useAuthenticatorVerify.js +45 -0
- package/lib/module/hooks/useAuthenticatorVerify.js.map +1 -0
- package/lib/module/hooks/usePhoneVerify.js +76 -0
- package/lib/module/hooks/usePhoneVerify.js.map +1 -0
- package/lib/module/icons/Google.js +22 -0
- package/lib/module/icons/Google.js.map +1 -0
- package/lib/module/index.js +10 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/storage/index.js +2 -0
- package/lib/module/storage/index.js.map +1 -0
- package/lib/module/storage/utils.js +30 -0
- package/lib/module/storage/utils.js.map +1 -0
- package/lib/module/types/adapter.js +2 -0
- package/lib/module/types/adapter.js.map +1 -0
- package/lib/module/types/auth.js +2 -0
- package/lib/module/types/auth.js.map +1 -0
- package/lib/module/types/db.js +2 -0
- package/lib/module/types/db.js.map +1 -0
- package/lib/module/types/functions.js +2 -0
- package/lib/module/types/functions.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/storage.js +2 -0
- package/lib/module/types/storage.js.map +1 -0
- package/lib/module/utils/validation.js +62 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/typescript/adapter/auth.d.ts +7 -0
- package/lib/typescript/adapter/auth.d.ts.map +1 -0
- package/lib/typescript/adapter/db.d.ts +5 -0
- package/lib/typescript/adapter/db.d.ts.map +1 -0
- package/lib/typescript/adapter/index.d.ts +9 -0
- package/lib/typescript/adapter/index.d.ts.map +1 -0
- package/lib/typescript/adapter/storage.d.ts +4 -0
- package/lib/typescript/adapter/storage.d.ts.map +1 -0
- package/lib/typescript/auth/functions.d.ts +4 -0
- package/lib/typescript/auth/functions.d.ts.map +1 -0
- package/lib/typescript/auth/index.d.ts +2 -0
- package/lib/typescript/auth/index.d.ts.map +1 -0
- package/lib/typescript/components/AuthenticatorVerify.d.ts +3 -0
- package/lib/typescript/components/AuthenticatorVerify.d.ts.map +1 -0
- package/lib/typescript/components/FirebaseSignIn.d.ts +6 -0
- package/lib/typescript/components/FirebaseSignIn.d.ts.map +1 -0
- package/lib/typescript/components/PhoneVerify.d.ts +6 -0
- package/lib/typescript/components/PhoneVerify.d.ts.map +1 -0
- package/lib/typescript/components/TwoFactorAuthModal.d.ts +3 -0
- package/lib/typescript/components/TwoFactorAuthModal.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +3 -0
- package/lib/typescript/components/index.d.ts.map +1 -0
- package/lib/typescript/contexts/FirebaseContext.d.ts +9 -0
- package/lib/typescript/contexts/FirebaseContext.d.ts.map +1 -0
- package/lib/typescript/contexts/index.d.ts +2 -0
- package/lib/typescript/contexts/index.d.ts.map +1 -0
- package/lib/typescript/db/index.d.ts +2 -0
- package/lib/typescript/db/index.d.ts.map +1 -0
- package/lib/typescript/db/utils.d.ts +6 -0
- package/lib/typescript/db/utils.d.ts.map +1 -0
- package/lib/typescript/hooks/backend.d.ts +2 -0
- package/lib/typescript/hooks/backend.d.ts.map +1 -0
- package/lib/typescript/hooks/index.d.ts +2 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts +8 -0
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts.map +1 -0
- package/lib/typescript/hooks/usePhoneVerify.d.ts +9 -0
- package/lib/typescript/hooks/usePhoneVerify.d.ts.map +1 -0
- package/lib/typescript/icons/Google.d.ts +5 -0
- package/lib/typescript/icons/Google.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +10 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/storage/index.d.ts +2 -0
- package/lib/typescript/storage/index.d.ts.map +1 -0
- package/lib/typescript/storage/utils.d.ts +4 -0
- package/lib/typescript/storage/utils.d.ts.map +1 -0
- package/lib/typescript/types/adapter.d.ts +6 -0
- package/lib/typescript/types/adapter.d.ts.map +1 -0
- package/lib/typescript/types/auth.d.ts +12 -0
- package/lib/typescript/types/auth.d.ts.map +1 -0
- package/lib/typescript/types/db.d.ts +8 -0
- package/lib/typescript/types/db.d.ts.map +1 -0
- package/lib/typescript/types/functions.d.ts +3 -0
- package/lib/typescript/types/functions.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +24 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/types/storage.d.ts +3 -0
- package/lib/typescript/types/storage.d.ts.map +1 -0
- package/lib/typescript/utils/validation.d.ts +21 -0
- package/lib/typescript/utils/validation.d.ts.map +1 -0
- package/package.json +29 -12
- package/src/adapter/auth.ts +474 -0
- package/src/adapter/db.ts +146 -0
- package/src/adapter/index.ts +30 -0
- package/src/adapter/storage.ts +58 -0
- package/src/auth/functions.ts +7 -0
- package/src/auth/index.ts +1 -0
- package/src/components/AuthenticatorVerify.tsx +75 -0
- package/src/components/FirebaseSignIn.tsx +187 -0
- package/src/components/PhoneVerify.tsx +102 -0
- package/src/components/TwoFactorAuthModal.tsx +133 -0
- package/src/components/index.ts +2 -0
- package/src/contexts/FirebaseContext.tsx +54 -0
- package/src/contexts/index.ts +1 -0
- package/src/db/index.ts +1 -0
- package/src/db/utils.ts +142 -0
- package/src/hooks/backend.ts +4 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAuthenticatorVerify.ts +45 -0
- package/src/hooks/usePhoneVerify.ts +76 -0
- package/src/icons/Google.tsx +24 -0
- package/src/index.ts +9 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/utils.ts +29 -0
- package/src/types/adapter.ts +13 -0
- package/src/types/auth.ts +13 -0
- package/src/types/db.ts +10 -0
- package/src/types/functions.ts +3 -0
- package/src/types/index.ts +26 -0
- package/src/types/storage.ts +3 -0
- package/src/utils/validation.ts +85 -0
package/src/db/utils.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { AnyObject, BaseQuery, isInequalityOperator, stringTransforms } from '@chem-po/core'
|
|
2
|
+
import {
|
|
3
|
+
collection,
|
|
4
|
+
collectionGroup,
|
|
5
|
+
limit as limitTo,
|
|
6
|
+
orderBy,
|
|
7
|
+
query,
|
|
8
|
+
startAfter,
|
|
9
|
+
where,
|
|
10
|
+
} from '@react-native-firebase/firestore'
|
|
11
|
+
import { Firestore, FirestoreBaseQuery, FirestoreCursor, FirestoreQuery } from '../types/db'
|
|
12
|
+
|
|
13
|
+
export const toFirestoreQuery = <T extends AnyObject>(
|
|
14
|
+
db: Firestore,
|
|
15
|
+
baseQuery: FirestoreBaseQuery<T>,
|
|
16
|
+
): FirestoreQuery<T> => {
|
|
17
|
+
const {
|
|
18
|
+
collection: collectionPath,
|
|
19
|
+
filters,
|
|
20
|
+
limit,
|
|
21
|
+
search,
|
|
22
|
+
sort,
|
|
23
|
+
isCollectionGroup,
|
|
24
|
+
cursor: startAfterDoc,
|
|
25
|
+
} = baseQuery
|
|
26
|
+
|
|
27
|
+
let q: FirestoreQuery<T> = (
|
|
28
|
+
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
29
|
+
) as FirestoreQuery<T>
|
|
30
|
+
|
|
31
|
+
if (filters) {
|
|
32
|
+
filters.forEach(({ key, operator, value }) => {
|
|
33
|
+
q = query(q, where(key, operator, value))
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (sort) {
|
|
38
|
+
q = query(q, orderBy(sort.key, sort.direction))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (startAfterDoc) {
|
|
42
|
+
q = query(q, startAfter(startAfterDoc))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (search?.paths?.length && search.query) {
|
|
46
|
+
const trimmed = (search.query || '').trim()
|
|
47
|
+
if (trimmed) {
|
|
48
|
+
q = query(
|
|
49
|
+
q,
|
|
50
|
+
where(search.paths[0].prop, '>=', trimmed),
|
|
51
|
+
where(search.paths[0].prop, '<=', `${trimmed}\uf8ff`),
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return limit ? query(q, limitTo(limit)) : q
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const toCursorQuery = <T extends AnyObject>(
|
|
60
|
+
db: Firestore,
|
|
61
|
+
baseQuery: FirestoreBaseQuery<T>,
|
|
62
|
+
cursor: FirestoreCursor | null,
|
|
63
|
+
): FirestoreQuery<T> => {
|
|
64
|
+
const { collection: collectionPath, filters, sort, isCollectionGroup, search, limit } = baseQuery
|
|
65
|
+
|
|
66
|
+
let q: FirestoreQuery<T> = (
|
|
67
|
+
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
68
|
+
) as FirestoreQuery<T>
|
|
69
|
+
|
|
70
|
+
if (filters) {
|
|
71
|
+
filters.forEach(({ key, operator, value }) => {
|
|
72
|
+
q = query(q, where(key, operator, value))
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (sort) {
|
|
77
|
+
q = query(q, orderBy(sort.key, sort.direction))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (search?.paths?.length && search.query) {
|
|
81
|
+
const trimmed = (search.query || '').trim()
|
|
82
|
+
if (trimmed) {
|
|
83
|
+
q = query(
|
|
84
|
+
q,
|
|
85
|
+
where(search.paths[0].prop, '>=', trimmed),
|
|
86
|
+
where(search.paths[0].prop, '<=', `${trimmed}\uf8ff`),
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (cursor) {
|
|
92
|
+
q = query(q, startAfter(cursor))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return limit ? query(q, limitTo(limit), limitTo(1)) : q
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const toFirestoreQueries = <T extends AnyObject>(
|
|
99
|
+
db: Firestore,
|
|
100
|
+
baseQuery: BaseQuery<T>,
|
|
101
|
+
cursors: Array<FirestoreCursor | null> | null,
|
|
102
|
+
): Array<FirestoreQuery<T>> => {
|
|
103
|
+
const { collection: collectionPath, filters, limit, search, sort, isCollectionGroup } = baseQuery
|
|
104
|
+
|
|
105
|
+
let q: FirestoreQuery<T> = (
|
|
106
|
+
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
107
|
+
) as FirestoreQuery<T>
|
|
108
|
+
if (filters) {
|
|
109
|
+
let filterSortKey: string | null = null
|
|
110
|
+
filters.forEach(({ key, operator, value }) => {
|
|
111
|
+
q = query(q, where(key, operator, value))
|
|
112
|
+
if (!filterSortKey && isInequalityOperator(operator) && (!sort || sort.key !== key)) {
|
|
113
|
+
filterSortKey = key
|
|
114
|
+
q = query(q, orderBy(key, 'asc'))
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (sort) {
|
|
120
|
+
q = query(q, orderBy(sort.key, sort.direction))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (cursors?.length) {
|
|
124
|
+
q = query(q, startAfter(cursors[cursors.length - 1]))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const queries =
|
|
128
|
+
search?.paths?.length && search.query
|
|
129
|
+
? search.paths.map(path => {
|
|
130
|
+
let trimmed = (search.query ?? '').trim()
|
|
131
|
+
if (!trimmed) return q
|
|
132
|
+
if (path.transform) trimmed = stringTransforms[path.transform](trimmed)
|
|
133
|
+
return query(
|
|
134
|
+
q,
|
|
135
|
+
where(path.prop, '>=', trimmed),
|
|
136
|
+
where(path.prop, '<=', `${trimmed}\uf8ff`),
|
|
137
|
+
)
|
|
138
|
+
})
|
|
139
|
+
: [q]
|
|
140
|
+
|
|
141
|
+
return queries.map(q0 => (limit ? query(q0, limitTo(limit)) : q0))
|
|
142
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './backend'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useAuth } from '@chem-po/react'
|
|
2
|
+
import { FirebaseAuthTypes } from '@react-native-firebase/auth'
|
|
3
|
+
import { useCallback, useState } from 'react'
|
|
4
|
+
import { useBackend } from './backend'
|
|
5
|
+
|
|
6
|
+
export const useAuthenticatorVerify = () => {
|
|
7
|
+
const [code, setCode] = useState('')
|
|
8
|
+
const [verifying, setVerifying] = useState(false)
|
|
9
|
+
const [error, setError] = useState('')
|
|
10
|
+
const twoFactorVerification = useAuth(s => s.multiFactorVerification)
|
|
11
|
+
const { auth } = useBackend()
|
|
12
|
+
// const { showSuccess, showError, showInfo } = useToast()
|
|
13
|
+
|
|
14
|
+
const handleVerify = useCallback(async () => {
|
|
15
|
+
const verify = auth.verifyMultiFactor
|
|
16
|
+
if (!verify) {
|
|
17
|
+
setError('Error - Two factor verification is not supported')
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
if (!code) return
|
|
21
|
+
if (!twoFactorVerification) {
|
|
22
|
+
setError('Error - No session found')
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
const resolver = twoFactorVerification.resolver as FirebaseAuthTypes.MultiFactorResolver
|
|
26
|
+
if (!resolver) {
|
|
27
|
+
setError('Error - No session found')
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
setVerifying(true)
|
|
31
|
+
try {
|
|
32
|
+
await verify(twoFactorVerification, code)
|
|
33
|
+
} catch (error) {
|
|
34
|
+
setError(error instanceof Error ? error.message : 'An unknown error occurred')
|
|
35
|
+
}
|
|
36
|
+
}, [code, auth, twoFactorVerification])
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
code,
|
|
40
|
+
setCode,
|
|
41
|
+
verifying,
|
|
42
|
+
error,
|
|
43
|
+
handleVerify,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PhoneEnrollmentFactor } from '@chem-po/core'
|
|
2
|
+
import { useAuth, useToast } from '@chem-po/react'
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { useBackend } from './backend'
|
|
5
|
+
|
|
6
|
+
export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendSmsCode: boolean) => {
|
|
7
|
+
const [code, setCode] = useState('')
|
|
8
|
+
const [verifying, setVerifying] = useState(false)
|
|
9
|
+
const [error, setError] = useState('')
|
|
10
|
+
|
|
11
|
+
const { auth } = useBackend()
|
|
12
|
+
const {multiFactorVerification: twoFactorVerification, enrollmentFactors} = useAuth()
|
|
13
|
+
|
|
14
|
+
// const [{ automaticallySendSmsCode }, setCookie] = useCookies(['automaticallySendSmsCode'])
|
|
15
|
+
|
|
16
|
+
const initSendCode = useRef(!!automaticallySendSmsCode)
|
|
17
|
+
|
|
18
|
+
const { showSuccess, showError, showInfo } = useToast()
|
|
19
|
+
|
|
20
|
+
const sendCode = useCallback(async () => {
|
|
21
|
+
if (!enrollmentFactors) {
|
|
22
|
+
showError('Error - No session found')
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
await auth.sendMultiFactorCode(factor, enrollmentFactors.multiFactorResolver)
|
|
26
|
+
}, [auth, factor, twoFactorVerification, showError])
|
|
27
|
+
|
|
28
|
+
const initSendCodeFunc = useRef(sendCode)
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (initSendCode.current) {
|
|
31
|
+
initSendCodeFunc.current()
|
|
32
|
+
}
|
|
33
|
+
}, [])
|
|
34
|
+
|
|
35
|
+
const handleVerify = useCallback(() => {
|
|
36
|
+
setVerifying(true)
|
|
37
|
+
setError('')
|
|
38
|
+
if (!twoFactorVerification) {
|
|
39
|
+
showError('Error - No session found')
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
const resolver = twoFactorVerification.resolver
|
|
43
|
+
if (!resolver) {
|
|
44
|
+
showError('Error - No resolver found')
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
const verificationId = twoFactorVerification.verificationId
|
|
48
|
+
if (!verificationId) {
|
|
49
|
+
showError('Error - No verification ID found')
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
const verify = auth.verifyMultiFactor
|
|
53
|
+
if (!verify) {
|
|
54
|
+
showError('Error - Two factor verification is not supported')
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
verify(twoFactorVerification, code)
|
|
58
|
+
.then(() => {
|
|
59
|
+
setVerifying(false)
|
|
60
|
+
setCode('')
|
|
61
|
+
showSuccess('Verification successful')
|
|
62
|
+
})
|
|
63
|
+
.catch(e => {
|
|
64
|
+
setVerifying(false)
|
|
65
|
+
setError(e.message || 'An error occurred')
|
|
66
|
+
})
|
|
67
|
+
}, [code, auth, showSuccess, showError])
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
code,
|
|
71
|
+
setCode,
|
|
72
|
+
verifying,
|
|
73
|
+
error,
|
|
74
|
+
handleVerify,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import Svg, { Path, SvgProps } from 'react-native-svg'
|
|
3
|
+
|
|
4
|
+
const SvgGoogle = (props: SvgProps) => (
|
|
5
|
+
<Svg width={24} height={24} viewBox="0 0 24 24" {...props}>
|
|
6
|
+
<Path
|
|
7
|
+
fill="#4285F4"
|
|
8
|
+
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
|
9
|
+
/>
|
|
10
|
+
<Path
|
|
11
|
+
fill="#34A853"
|
|
12
|
+
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
|
13
|
+
/>
|
|
14
|
+
<Path
|
|
15
|
+
fill="#FBBC05"
|
|
16
|
+
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
|
17
|
+
/>
|
|
18
|
+
<Path
|
|
19
|
+
fill="#EA4335"
|
|
20
|
+
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
|
21
|
+
/>
|
|
22
|
+
</Svg>
|
|
23
|
+
)
|
|
24
|
+
export default SvgGoogle
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './utils'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FileValue, LocalFileValue, OnUploadProgress } from '@chem-po/core'
|
|
2
|
+
import { FirebaseStorageTypes, ref, uploadString } from '@react-native-firebase/storage'
|
|
3
|
+
|
|
4
|
+
export const uploadFileValue = async (
|
|
5
|
+
storage: FirebaseStorageTypes.Module,
|
|
6
|
+
path: string,
|
|
7
|
+
file: LocalFileValue | FileValue | null | undefined,
|
|
8
|
+
onUploadProgress: OnUploadProgress,
|
|
9
|
+
): Promise<FileValue | null> => {
|
|
10
|
+
if (!file) return null
|
|
11
|
+
const { dataUrl, type, filename } = file as LocalFileValue
|
|
12
|
+
if (!dataUrl) return file
|
|
13
|
+
|
|
14
|
+
const storageRef = ref(storage, path)
|
|
15
|
+
const uploadTask = uploadString(storageRef, dataUrl, 'data_url')
|
|
16
|
+
|
|
17
|
+
uploadTask.on('state_changed', snapshot => {
|
|
18
|
+
const percent = snapshot.bytesTransferred / snapshot.totalBytes
|
|
19
|
+
onUploadProgress({ total: snapshot.totalBytes, loaded: snapshot.bytesTransferred, percent })
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
uploadTask
|
|
24
|
+
.then(() => {
|
|
25
|
+
resolve({ storagePath: path, type, filename })
|
|
26
|
+
})
|
|
27
|
+
.catch(reject)
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BackendAdapterInterface, BaseAuthProvider } from '@chem-po/core'
|
|
2
|
+
import { FirebaseStorageTypes } from '@react-native-firebase/storage'
|
|
3
|
+
import { EmailPasswordLogin, User } from './auth'
|
|
4
|
+
import { FirestoreCursor } from './db'
|
|
5
|
+
|
|
6
|
+
export type FirebaseBackendAdapter<AuthProvider extends BaseAuthProvider> = BackendAdapterInterface<
|
|
7
|
+
AuthProvider,
|
|
8
|
+
User,
|
|
9
|
+
EmailPasswordLogin,
|
|
10
|
+
FirestoreCursor,
|
|
11
|
+
Blob,
|
|
12
|
+
FirebaseStorageTypes.FullMetadata
|
|
13
|
+
>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseUserRole } from '@chem-po/core'
|
|
2
|
+
import { getAuth } from '@react-native-firebase/auth'
|
|
3
|
+
|
|
4
|
+
export type Auth = ReturnType<typeof getAuth>
|
|
5
|
+
export interface User {
|
|
6
|
+
uid: string
|
|
7
|
+
role: BaseUserRole
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface EmailPasswordLogin {
|
|
11
|
+
email: string
|
|
12
|
+
password: string
|
|
13
|
+
}
|
package/src/types/db.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// import { AnyObject } from '@chem-po/core'
|
|
2
|
+
import { AnyObject, BaseQuery, OnItemsData } from '@chem-po/core'
|
|
3
|
+
import { FirebaseFirestoreTypes } from '@react-native-firebase/firestore'
|
|
4
|
+
|
|
5
|
+
export type Firestore = FirebaseFirestoreTypes.Module
|
|
6
|
+
export type FirestoreCursor = FirebaseFirestoreTypes.QueryDocumentSnapshot
|
|
7
|
+
export type FirestoreBaseQuery<T extends AnyObject> = BaseQuery<T, FirestoreCursor>
|
|
8
|
+
export type FirestoreQuery<T extends AnyObject> = FirebaseFirestoreTypes.Query<T>
|
|
9
|
+
// export type FirestoreQuery<T extends AnyObject> = BaseQuery<T, FirestoreCursor>
|
|
10
|
+
export type FirestoreOnItemsData<T extends AnyObject> = OnItemsData<T, FirestoreCursor>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ReactNativeFirebase } from '@react-native-firebase/app'
|
|
2
|
+
import { FirebaseAuthTypes } from '@react-native-firebase/auth'
|
|
3
|
+
import { FirebaseFirestoreTypes } from '@react-native-firebase/firestore'
|
|
4
|
+
import { FirebaseStorageTypes } from '@react-native-firebase/storage'
|
|
5
|
+
|
|
6
|
+
export type FirebaseAuth = FirebaseAuthTypes.Module
|
|
7
|
+
export type FirebaseFirestore = FirebaseFirestoreTypes.Module
|
|
8
|
+
export type FirebaseStorage = FirebaseStorageTypes.Module
|
|
9
|
+
|
|
10
|
+
export interface FirebaseConfig {
|
|
11
|
+
apiKey: string
|
|
12
|
+
authDomain: string
|
|
13
|
+
projectId: string
|
|
14
|
+
storageBucket: string
|
|
15
|
+
messagingSenderId: string
|
|
16
|
+
appId: string
|
|
17
|
+
measurementId?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface FirebaseContextValue {
|
|
21
|
+
loading: boolean
|
|
22
|
+
app: ReactNativeFirebase.FirebaseApp | null
|
|
23
|
+
auth: FirebaseAuth
|
|
24
|
+
firestore: FirebaseFirestore
|
|
25
|
+
storage: FirebaseStorage
|
|
26
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { BaseAuthProvider, GoogleAuthProvider } from '@chem-po/core'
|
|
2
|
+
|
|
3
|
+
interface ValidationResult {
|
|
4
|
+
isValid: boolean
|
|
5
|
+
errors: string[]
|
|
6
|
+
warnings: string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Validates Firebase authentication configuration to help identify common setup issues
|
|
11
|
+
*/
|
|
12
|
+
export const validateAuthConfiguration = (providers: BaseAuthProvider[]): ValidationResult => {
|
|
13
|
+
const errors: string[] = []
|
|
14
|
+
const warnings: string[] = []
|
|
15
|
+
|
|
16
|
+
// Check for Google provider configuration
|
|
17
|
+
const googleProvider = providers.find(p => p.name === 'google') as GoogleAuthProvider | undefined
|
|
18
|
+
|
|
19
|
+
if (googleProvider) {
|
|
20
|
+
if (!googleProvider.webClientId) {
|
|
21
|
+
errors.push(
|
|
22
|
+
'Google provider is missing webClientId. ' +
|
|
23
|
+
'Get this from Firebase Console > Authentication > Sign-in method > Google > Web SDK configuration',
|
|
24
|
+
)
|
|
25
|
+
} else if (!googleProvider.webClientId.includes('.apps.googleusercontent.com')) {
|
|
26
|
+
warnings.push(
|
|
27
|
+
'Google webClientId format looks incorrect. Expected format: "xxx.apps.googleusercontent.com"',
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check environment
|
|
33
|
+
if (typeof process === 'undefined') {
|
|
34
|
+
warnings.push('Process environment is not available - some features may not work as expected')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check for Firebase configuration files (platform-specific warnings)
|
|
38
|
+
const isExpo =
|
|
39
|
+
typeof process !== 'undefined' && process.env?.EXPO_PUBLIC_ENVIRONMENT !== undefined
|
|
40
|
+
if (!isExpo) {
|
|
41
|
+
warnings.push(
|
|
42
|
+
'Ensure Firebase configuration files are present:\n' +
|
|
43
|
+
'- iOS: GoogleService-Info.plist in ios/ directory\n' +
|
|
44
|
+
'- Android: google-services.json in android/app/ directory',
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
isValid: errors.length === 0,
|
|
50
|
+
errors,
|
|
51
|
+
warnings,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Logs validation results with appropriate console methods
|
|
57
|
+
*/
|
|
58
|
+
export const logValidationResults = (
|
|
59
|
+
result: ValidationResult,
|
|
60
|
+
packageName = '@chem-po/firebase-native',
|
|
61
|
+
) => {
|
|
62
|
+
if (result.errors.length > 0) {
|
|
63
|
+
console.error(`[${packageName}] Configuration errors found:`)
|
|
64
|
+
result.errors.forEach(error => console.error(` ❌ ${error}`))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (result.warnings.length > 0) {
|
|
68
|
+
console.warn(`[${packageName}] Configuration warnings:`)
|
|
69
|
+
result.warnings.forEach(warning => console.warn(` ⚠️ ${warning}`))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (result.isValid && result.warnings.length === 0) {
|
|
73
|
+
console.log(`[${packageName}] ✅ Configuration validation passed`)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validates and logs Firebase auth configuration
|
|
79
|
+
* Call this during development to identify setup issues early
|
|
80
|
+
*/
|
|
81
|
+
export const validateAndLogAuthConfig = (providers: BaseAuthProvider[]) => {
|
|
82
|
+
const result = validateAuthConfiguration(providers)
|
|
83
|
+
logValidationResults(result)
|
|
84
|
+
return result
|
|
85
|
+
}
|