@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.
Files changed (212) hide show
  1. package/README.md +215 -0
  2. package/lib/commonjs/adapter/auth.js +431 -0
  3. package/lib/commonjs/adapter/auth.js.map +1 -0
  4. package/lib/commonjs/adapter/db.js +103 -0
  5. package/lib/commonjs/adapter/db.js.map +1 -0
  6. package/lib/commonjs/adapter/index.js +16 -0
  7. package/lib/commonjs/adapter/index.js.map +1 -0
  8. package/lib/commonjs/adapter/storage.js +52 -0
  9. package/lib/commonjs/adapter/storage.js.map +1 -0
  10. package/lib/commonjs/auth/functions.js +11 -0
  11. package/lib/commonjs/auth/functions.js.map +1 -0
  12. package/lib/commonjs/auth/index.js +17 -0
  13. package/lib/commonjs/auth/index.js.map +1 -0
  14. package/lib/commonjs/components/AuthenticatorVerify.js +90 -0
  15. package/lib/commonjs/components/AuthenticatorVerify.js.map +1 -0
  16. package/lib/commonjs/components/FirebaseSignIn.js +196 -0
  17. package/lib/commonjs/components/FirebaseSignIn.js.map +1 -0
  18. package/lib/commonjs/components/PhoneVerify.js +123 -0
  19. package/lib/commonjs/components/PhoneVerify.js.map +1 -0
  20. package/lib/commonjs/components/TwoFactorAuthModal.js +118 -0
  21. package/lib/commonjs/components/TwoFactorAuthModal.js.map +1 -0
  22. package/lib/commonjs/components/index.js +28 -0
  23. package/lib/commonjs/components/index.js.map +1 -0
  24. package/lib/commonjs/contexts/FirebaseContext.js +48 -0
  25. package/lib/commonjs/contexts/FirebaseContext.js.map +1 -0
  26. package/lib/commonjs/contexts/index.js +17 -0
  27. package/lib/commonjs/contexts/index.js.map +1 -0
  28. package/lib/commonjs/db/index.js +17 -0
  29. package/lib/commonjs/db/index.js.map +1 -0
  30. package/lib/commonjs/db/utils.js +120 -0
  31. package/lib/commonjs/db/utils.js.map +1 -0
  32. package/lib/commonjs/hooks/backend.js +12 -0
  33. package/lib/commonjs/hooks/backend.js.map +1 -0
  34. package/lib/commonjs/hooks/index.js +17 -0
  35. package/lib/commonjs/hooks/index.js.map +1 -0
  36. package/lib/commonjs/hooks/useAuthenticatorVerify.js +52 -0
  37. package/lib/commonjs/hooks/useAuthenticatorVerify.js.map +1 -0
  38. package/lib/commonjs/hooks/usePhoneVerify.js +83 -0
  39. package/lib/commonjs/hooks/usePhoneVerify.js.map +1 -0
  40. package/lib/commonjs/icons/Google.js +29 -0
  41. package/lib/commonjs/icons/Google.js.map +1 -0
  42. package/lib/commonjs/index.js +105 -0
  43. package/lib/commonjs/index.js.map +1 -0
  44. package/lib/commonjs/storage/index.js +17 -0
  45. package/lib/commonjs/storage/index.js.map +1 -0
  46. package/lib/commonjs/storage/utils.js +37 -0
  47. package/lib/commonjs/storage/utils.js.map +1 -0
  48. package/lib/commonjs/types/adapter.js +6 -0
  49. package/lib/commonjs/types/adapter.js.map +1 -0
  50. package/lib/commonjs/types/auth.js +6 -0
  51. package/lib/commonjs/types/auth.js.map +1 -0
  52. package/lib/commonjs/types/db.js +6 -0
  53. package/lib/commonjs/types/db.js.map +1 -0
  54. package/lib/commonjs/types/functions.js +6 -0
  55. package/lib/commonjs/types/functions.js.map +1 -0
  56. package/lib/commonjs/types/index.js +6 -0
  57. package/lib/commonjs/types/index.js.map +1 -0
  58. package/lib/commonjs/types/storage.js +6 -0
  59. package/lib/commonjs/types/storage.js.map +1 -0
  60. package/lib/commonjs/utils/validation.js +71 -0
  61. package/lib/commonjs/utils/validation.js.map +1 -0
  62. package/lib/module/adapter/auth.js +424 -0
  63. package/lib/module/adapter/auth.js.map +1 -0
  64. package/lib/module/adapter/db.js +96 -0
  65. package/lib/module/adapter/db.js.map +1 -0
  66. package/lib/module/adapter/index.js +9 -0
  67. package/lib/module/adapter/index.js.map +1 -0
  68. package/lib/module/adapter/storage.js +45 -0
  69. package/lib/module/adapter/storage.js.map +1 -0
  70. package/lib/module/auth/functions.js +3 -0
  71. package/lib/module/auth/functions.js.map +1 -0
  72. package/lib/module/auth/index.js +2 -0
  73. package/lib/module/auth/index.js.map +1 -0
  74. package/lib/module/components/AuthenticatorVerify.js +82 -0
  75. package/lib/module/components/AuthenticatorVerify.js.map +1 -0
  76. package/lib/module/components/FirebaseSignIn.js +187 -0
  77. package/lib/module/components/FirebaseSignIn.js.map +1 -0
  78. package/lib/module/components/PhoneVerify.js +116 -0
  79. package/lib/module/components/PhoneVerify.js.map +1 -0
  80. package/lib/module/components/TwoFactorAuthModal.js +110 -0
  81. package/lib/module/components/TwoFactorAuthModal.js.map +1 -0
  82. package/lib/module/components/index.js +3 -0
  83. package/lib/module/components/index.js.map +1 -0
  84. package/lib/module/contexts/FirebaseContext.js +39 -0
  85. package/lib/module/contexts/FirebaseContext.js.map +1 -0
  86. package/lib/module/contexts/index.js +2 -0
  87. package/lib/module/contexts/index.js.map +1 -0
  88. package/lib/module/db/index.js +2 -0
  89. package/lib/module/db/index.js.map +1 -0
  90. package/lib/module/db/utils.js +111 -0
  91. package/lib/module/db/utils.js.map +1 -0
  92. package/lib/module/hooks/backend.js +5 -0
  93. package/lib/module/hooks/backend.js.map +1 -0
  94. package/lib/module/hooks/index.js +2 -0
  95. package/lib/module/hooks/index.js.map +1 -0
  96. package/lib/module/hooks/useAuthenticatorVerify.js +45 -0
  97. package/lib/module/hooks/useAuthenticatorVerify.js.map +1 -0
  98. package/lib/module/hooks/usePhoneVerify.js +76 -0
  99. package/lib/module/hooks/usePhoneVerify.js.map +1 -0
  100. package/lib/module/icons/Google.js +22 -0
  101. package/lib/module/icons/Google.js.map +1 -0
  102. package/lib/module/index.js +10 -0
  103. package/lib/module/index.js.map +1 -0
  104. package/lib/module/storage/index.js +2 -0
  105. package/lib/module/storage/index.js.map +1 -0
  106. package/lib/module/storage/utils.js +30 -0
  107. package/lib/module/storage/utils.js.map +1 -0
  108. package/lib/module/types/adapter.js +2 -0
  109. package/lib/module/types/adapter.js.map +1 -0
  110. package/lib/module/types/auth.js +2 -0
  111. package/lib/module/types/auth.js.map +1 -0
  112. package/lib/module/types/db.js +2 -0
  113. package/lib/module/types/db.js.map +1 -0
  114. package/lib/module/types/functions.js +2 -0
  115. package/lib/module/types/functions.js.map +1 -0
  116. package/lib/module/types/index.js +2 -0
  117. package/lib/module/types/index.js.map +1 -0
  118. package/lib/module/types/storage.js +2 -0
  119. package/lib/module/types/storage.js.map +1 -0
  120. package/lib/module/utils/validation.js +62 -0
  121. package/lib/module/utils/validation.js.map +1 -0
  122. package/lib/typescript/adapter/auth.d.ts +7 -0
  123. package/lib/typescript/adapter/auth.d.ts.map +1 -0
  124. package/lib/typescript/adapter/db.d.ts +5 -0
  125. package/lib/typescript/adapter/db.d.ts.map +1 -0
  126. package/lib/typescript/adapter/index.d.ts +9 -0
  127. package/lib/typescript/adapter/index.d.ts.map +1 -0
  128. package/lib/typescript/adapter/storage.d.ts +4 -0
  129. package/lib/typescript/adapter/storage.d.ts.map +1 -0
  130. package/lib/typescript/auth/functions.d.ts +4 -0
  131. package/lib/typescript/auth/functions.d.ts.map +1 -0
  132. package/lib/typescript/auth/index.d.ts +2 -0
  133. package/lib/typescript/auth/index.d.ts.map +1 -0
  134. package/lib/typescript/components/AuthenticatorVerify.d.ts +3 -0
  135. package/lib/typescript/components/AuthenticatorVerify.d.ts.map +1 -0
  136. package/lib/typescript/components/FirebaseSignIn.d.ts +6 -0
  137. package/lib/typescript/components/FirebaseSignIn.d.ts.map +1 -0
  138. package/lib/typescript/components/PhoneVerify.d.ts +6 -0
  139. package/lib/typescript/components/PhoneVerify.d.ts.map +1 -0
  140. package/lib/typescript/components/TwoFactorAuthModal.d.ts +3 -0
  141. package/lib/typescript/components/TwoFactorAuthModal.d.ts.map +1 -0
  142. package/lib/typescript/components/index.d.ts +3 -0
  143. package/lib/typescript/components/index.d.ts.map +1 -0
  144. package/lib/typescript/contexts/FirebaseContext.d.ts +9 -0
  145. package/lib/typescript/contexts/FirebaseContext.d.ts.map +1 -0
  146. package/lib/typescript/contexts/index.d.ts +2 -0
  147. package/lib/typescript/contexts/index.d.ts.map +1 -0
  148. package/lib/typescript/db/index.d.ts +2 -0
  149. package/lib/typescript/db/index.d.ts.map +1 -0
  150. package/lib/typescript/db/utils.d.ts +6 -0
  151. package/lib/typescript/db/utils.d.ts.map +1 -0
  152. package/lib/typescript/hooks/backend.d.ts +2 -0
  153. package/lib/typescript/hooks/backend.d.ts.map +1 -0
  154. package/lib/typescript/hooks/index.d.ts +2 -0
  155. package/lib/typescript/hooks/index.d.ts.map +1 -0
  156. package/lib/typescript/hooks/useAuthenticatorVerify.d.ts +8 -0
  157. package/lib/typescript/hooks/useAuthenticatorVerify.d.ts.map +1 -0
  158. package/lib/typescript/hooks/usePhoneVerify.d.ts +9 -0
  159. package/lib/typescript/hooks/usePhoneVerify.d.ts.map +1 -0
  160. package/lib/typescript/icons/Google.d.ts +5 -0
  161. package/lib/typescript/icons/Google.d.ts.map +1 -0
  162. package/lib/typescript/index.d.ts +10 -0
  163. package/lib/typescript/index.d.ts.map +1 -0
  164. package/lib/typescript/storage/index.d.ts +2 -0
  165. package/lib/typescript/storage/index.d.ts.map +1 -0
  166. package/lib/typescript/storage/utils.d.ts +4 -0
  167. package/lib/typescript/storage/utils.d.ts.map +1 -0
  168. package/lib/typescript/types/adapter.d.ts +6 -0
  169. package/lib/typescript/types/adapter.d.ts.map +1 -0
  170. package/lib/typescript/types/auth.d.ts +12 -0
  171. package/lib/typescript/types/auth.d.ts.map +1 -0
  172. package/lib/typescript/types/db.d.ts +8 -0
  173. package/lib/typescript/types/db.d.ts.map +1 -0
  174. package/lib/typescript/types/functions.d.ts +3 -0
  175. package/lib/typescript/types/functions.d.ts.map +1 -0
  176. package/lib/typescript/types/index.d.ts +24 -0
  177. package/lib/typescript/types/index.d.ts.map +1 -0
  178. package/lib/typescript/types/storage.d.ts +3 -0
  179. package/lib/typescript/types/storage.d.ts.map +1 -0
  180. package/lib/typescript/utils/validation.d.ts +21 -0
  181. package/lib/typescript/utils/validation.d.ts.map +1 -0
  182. package/package.json +29 -12
  183. package/src/adapter/auth.ts +474 -0
  184. package/src/adapter/db.ts +146 -0
  185. package/src/adapter/index.ts +30 -0
  186. package/src/adapter/storage.ts +58 -0
  187. package/src/auth/functions.ts +7 -0
  188. package/src/auth/index.ts +1 -0
  189. package/src/components/AuthenticatorVerify.tsx +75 -0
  190. package/src/components/FirebaseSignIn.tsx +187 -0
  191. package/src/components/PhoneVerify.tsx +102 -0
  192. package/src/components/TwoFactorAuthModal.tsx +133 -0
  193. package/src/components/index.ts +2 -0
  194. package/src/contexts/FirebaseContext.tsx +54 -0
  195. package/src/contexts/index.ts +1 -0
  196. package/src/db/index.ts +1 -0
  197. package/src/db/utils.ts +142 -0
  198. package/src/hooks/backend.ts +4 -0
  199. package/src/hooks/index.ts +1 -0
  200. package/src/hooks/useAuthenticatorVerify.ts +45 -0
  201. package/src/hooks/usePhoneVerify.ts +76 -0
  202. package/src/icons/Google.tsx +24 -0
  203. package/src/index.ts +9 -0
  204. package/src/storage/index.ts +1 -0
  205. package/src/storage/utils.ts +29 -0
  206. package/src/types/adapter.ts +13 -0
  207. package/src/types/auth.ts +13 -0
  208. package/src/types/db.ts +10 -0
  209. package/src/types/functions.ts +3 -0
  210. package/src/types/index.ts +26 -0
  211. package/src/types/storage.ts +3 -0
  212. package/src/utils/validation.ts +85 -0
@@ -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,4 @@
1
+ import { useBackendBase } from '@chem-po/react'
2
+ // import { FirebaseBackendAdapter } from '../types/adapter'
3
+
4
+ export const useBackend = () => useBackendBase()
@@ -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,9 @@
1
+ export * from './adapter'
2
+ export * from './auth'
3
+ export * from './components'
4
+ export * from './contexts'
5
+ export * from './db'
6
+ export * from './hooks'
7
+ export * from './storage'
8
+ export * from './types'
9
+ export * from './utils/validation'
@@ -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
+ }
@@ -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,3 @@
1
+ import { getFunctions } from '@react-native-firebase/functions'
2
+
3
+ export type Functions = ReturnType<typeof getFunctions>
@@ -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,3 @@
1
+ import { getStorage } from '@react-native-firebase/storage'
2
+
3
+ export type Storage = ReturnType<typeof getStorage>
@@ -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
+ }