@react-native-firebase/auth 25.1.0 → 26.0.0

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 (115) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/RNFBAuth.podspec +14 -6
  3. package/android/build.gradle +23 -0
  4. package/android/src/main/java/io/invertase/firebase/auth/{ReactNativeFirebaseAuthModule.java → NativeRNFBTurboAuth.java} +122 -102
  5. package/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthPackage.java +1 -1
  6. package/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthSyncException.java +35 -0
  7. package/android/src/main/java/io/invertase/firebase/auth/generated/java/com/facebook/fbreact/specs/NativeRNFBTurboAuthSpec.java +308 -0
  8. package/android/src/main/java/io/invertase/firebase/auth/generated/jni/CMakeLists.txt +36 -0
  9. package/android/src/main/java/io/invertase/firebase/auth/generated/jni/RNFBAuthTurboModules-generated.cpp +392 -0
  10. package/android/src/main/java/io/invertase/firebase/auth/generated/jni/RNFBAuthTurboModules.h +31 -0
  11. package/android/src/main/java/io/invertase/firebase/auth/generated/jni/react/renderer/components/RNFBAuthTurboModules/RNFBAuthTurboModulesJSI-generated.cpp +538 -0
  12. package/android/src/main/java/io/invertase/firebase/auth/generated/jni/react/renderer/components/RNFBAuthTurboModules/RNFBAuthTurboModulesJSI.h +611 -0
  13. package/app.plugin.js +1 -1
  14. package/dist/module/ConfirmationResult.js.map +1 -1
  15. package/dist/module/MultiFactorResolver.js.map +1 -1
  16. package/dist/module/PhoneAuthListener.js +3 -4
  17. package/dist/module/PhoneAuthListener.js.map +1 -1
  18. package/dist/module/TotpMultiFactorGenerator.js +1 -1
  19. package/dist/module/TotpMultiFactorGenerator.js.map +1 -1
  20. package/dist/module/TotpSecret.js +15 -9
  21. package/dist/module/TotpSecret.js.map +1 -1
  22. package/dist/module/User.js +1 -1
  23. package/dist/module/User.js.map +1 -1
  24. package/dist/module/getMultiFactorResolver.js +2 -2
  25. package/dist/module/getMultiFactorResolver.js.map +1 -1
  26. package/dist/module/index.js +1221 -6
  27. package/dist/module/index.js.map +1 -1
  28. package/dist/module/internal/syncNativeError.js +75 -0
  29. package/dist/module/internal/syncNativeError.js.map +1 -0
  30. package/dist/module/multiFactor.js +5 -3
  31. package/dist/module/multiFactor.js.map +1 -1
  32. package/dist/module/providers/PhoneAuthProvider.js +4 -4
  33. package/dist/module/providers/PhoneAuthProvider.js.map +1 -1
  34. package/dist/module/types/auth.js.map +1 -1
  35. package/dist/module/version.js +1 -1
  36. package/dist/module/web/RNFBAuthModule.js +13 -7
  37. package/dist/module/web/RNFBAuthModule.js.map +1 -1
  38. package/dist/typescript/lib/ConfirmationResult.d.ts +2 -2
  39. package/dist/typescript/lib/ConfirmationResult.d.ts.map +1 -1
  40. package/dist/typescript/lib/MultiFactorResolver.d.ts +6 -6
  41. package/dist/typescript/lib/MultiFactorResolver.d.ts.map +1 -1
  42. package/dist/typescript/lib/PhoneAuthListener.d.ts +1 -4
  43. package/dist/typescript/lib/PhoneAuthListener.d.ts.map +1 -1
  44. package/dist/typescript/lib/TotpSecret.d.ts +2 -4
  45. package/dist/typescript/lib/TotpSecret.d.ts.map +1 -1
  46. package/dist/typescript/lib/User.d.ts +13 -13
  47. package/dist/typescript/lib/User.d.ts.map +1 -1
  48. package/dist/typescript/lib/getMultiFactorResolver.d.ts +5 -5
  49. package/dist/typescript/lib/getMultiFactorResolver.d.ts.map +1 -1
  50. package/dist/typescript/lib/index.d.ts +377 -4
  51. package/dist/typescript/lib/index.d.ts.map +1 -1
  52. package/dist/typescript/lib/internal/syncNativeError.d.ts +6 -0
  53. package/dist/typescript/lib/internal/syncNativeError.d.ts.map +1 -0
  54. package/dist/typescript/lib/multiFactor.d.ts +9 -9
  55. package/dist/typescript/lib/multiFactor.d.ts.map +1 -1
  56. package/dist/typescript/lib/providers/PhoneAuthProvider.d.ts.map +1 -1
  57. package/dist/typescript/lib/types/auth.d.ts +13 -0
  58. package/dist/typescript/lib/types/auth.d.ts.map +1 -1
  59. package/dist/typescript/lib/types/internal.d.ts +44 -47
  60. package/dist/typescript/lib/types/internal.d.ts.map +1 -1
  61. package/dist/typescript/lib/version.d.ts +1 -1
  62. package/dist/typescript/lib/web/RNFBAuthModule.d.ts +4 -4
  63. package/dist/typescript/lib/web/RNFBAuthModule.d.ts.map +1 -1
  64. package/ios/RNFBAuth/RNFBAuthModule.h +2 -2
  65. package/ios/RNFBAuth/{RNFBAuthModule.m → RNFBAuthModule.mm} +408 -297
  66. package/ios/RNFBAuth.xcodeproj/project.pbxproj +8 -8
  67. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  68. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  69. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  70. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  71. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  72. package/ios/generated/RCTThirdPartyComponentsProvider.mm +23 -0
  73. package/ios/generated/RNFBAuthTurboModules/RNFBAuthTurboModules-generated.mm +459 -0
  74. package/ios/generated/RNFBAuthTurboModules/RNFBAuthTurboModules.h +341 -0
  75. package/ios/generated/RNFBAuthTurboModulesJSI-generated.cpp +538 -0
  76. package/ios/generated/RNFBAuthTurboModulesJSI.h +611 -0
  77. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  78. package/lib/ConfirmationResult.ts +3 -6
  79. package/lib/MultiFactorResolver.ts +8 -8
  80. package/lib/PhoneAuthListener.ts +6 -10
  81. package/lib/TotpMultiFactorGenerator.ts +1 -1
  82. package/lib/TotpSecret.ts +22 -9
  83. package/lib/User.ts +27 -38
  84. package/lib/getMultiFactorResolver.ts +9 -11
  85. package/lib/index.ts +1836 -6
  86. package/lib/internal/syncNativeError.ts +89 -0
  87. package/lib/multiFactor.ts +25 -16
  88. package/lib/providers/PhoneAuthProvider.ts +9 -22
  89. package/lib/types/auth.ts +15 -0
  90. package/lib/types/internal.ts +54 -63
  91. package/lib/version.ts +1 -1
  92. package/lib/web/RNFBAuthModule.ts +13 -10
  93. package/package.json +30 -5
  94. package/plugin/build/app.plugin.d.ts +2 -0
  95. package/plugin/build/app.plugin.js +6 -0
  96. package/plugin/src/app.plugin.ts +3 -0
  97. package/plugin/tsconfig.tsbuildinfo +1 -1
  98. package/react-native.config.js +9 -0
  99. package/specs/NativeRNFBTurboAuth.ts +143 -0
  100. package/typedoc.json +0 -1
  101. package/dist/module/modular.js +0 -793
  102. package/dist/module/modular.js.map +0 -1
  103. package/dist/module/namespaced.js +0 -522
  104. package/dist/module/namespaced.js.map +0 -1
  105. package/dist/module/types/namespaced.js +0 -62
  106. package/dist/module/types/namespaced.js.map +0 -1
  107. package/dist/typescript/lib/modular.d.ts +0 -370
  108. package/dist/typescript/lib/modular.d.ts.map +0 -1
  109. package/dist/typescript/lib/namespaced.d.ts +0 -12
  110. package/dist/typescript/lib/namespaced.d.ts.map +0 -1
  111. package/dist/typescript/lib/types/namespaced.d.ts +0 -2185
  112. package/dist/typescript/lib/types/namespaced.d.ts.map +0 -1
  113. package/lib/modular.ts +0 -1166
  114. package/lib/namespaced.ts +0 -849
  115. package/lib/types/namespaced.ts +0 -2350
@@ -16,14 +16,1229 @@
16
16
  * limitations under the License.
17
17
  *
18
18
  */
19
- // modular API
20
19
 
20
+ /**
21
+ * Modular Auth API for React Native Firebase.
22
+ *
23
+ * Most exports mirror the [firebase-js-sdk modular Auth API](https://firebase.google.com/docs/reference/js/auth).
24
+ * Remarks on individual symbols call out React Native-specific behavior, unsupported
25
+ * web-only APIs, and return-type differences.
26
+ *
27
+ * @packageDocumentation
28
+ */
29
+
30
+ import "./types/internal.js";
21
31
  export { ActionCodeURL } from "./ActionCodeURL.js";
22
32
  export { AuthCredential, EmailAuthCredential, OAuthCredential, PhoneAuthCredential } from "./credentials/index.js";
23
- export * from "./modular.js";
33
+ import { isAndroid, isBoolean, isNull, isOther, isString, isValidUrl, parseListenerOrObserver } from '@react-native-firebase/app/dist/module/common';
34
+ import { setReactNativeModule } from '@react-native-firebase/app/dist/module/internal/nativeModule';
35
+ import { FirebaseModule, getOrCreateModularInstance } from '@react-native-firebase/app/dist/module/internal';
36
+ import ConfirmationResultClass from "./ConfirmationResult.js";
37
+ import { ActionCodeURL } from "./ActionCodeURL.js";
38
+ import { PhoneAuthState } from "./PhoneAuthState.js";
39
+ import PhoneAuthListenerClass from "./PhoneAuthListener.js";
40
+ import PhoneMultiFactorGenerator from "./PhoneMultiFactorGenerator.js";
41
+ import TotpMultiFactorGenerator from "./TotpMultiFactorGenerator.js";
42
+ import { TotpSecret } from "./TotpSecret.js";
43
+ import Settings from "./Settings.js";
44
+ import UserClass from "./User.js";
45
+ import { getMultiFactorResolver as createMultiFactorResolver } from "./getMultiFactorResolver.js";
46
+ import { MultiFactorUser as MultiFactorUserModule } from "./multiFactor.js";
47
+ import AppleAuthProvider from "./providers/AppleAuthProvider.js";
48
+ import EmailAuthProvider from "./providers/EmailAuthProvider.js";
49
+ import FacebookAuthProvider from "./providers/FacebookAuthProvider.js";
50
+ import GithubAuthProvider from "./providers/GithubAuthProvider.js";
51
+ import GoogleAuthProvider from "./providers/GoogleAuthProvider.js";
52
+ import OAuthProvider from "./providers/OAuthProvider.js";
53
+ import OIDCAuthProvider from "./providers/OIDCAuthProvider.js";
54
+ import PhoneAuthProvider from "./providers/PhoneAuthProvider.js";
55
+ import TwitterAuthProvider from "./providers/TwitterAuthProvider.js";
56
+ import { version } from "./version.js";
57
+ import { ActionCodeOperation, FactorId, OperationType, ProviderId, SignInMethod } from "./constants.js";
58
+ import fallBackModule from './web/RNFBAuthModule';
59
+ import { PasswordPolicyMixin } from "./password-policy/PasswordPolicyMixin.js";
60
+ const nativeEvents = ['auth_state_changed', 'auth_id_token_changed', 'phone_auth_state_changed'];
61
+ const namespace = 'auth';
62
+ const nativeModuleName = 'NativeRNFBTurboAuth';
63
+ const config = {
64
+ namespace,
65
+ nativeModuleName,
66
+ nativeEvents,
67
+ hasMultiAppSupport: true,
68
+ hasCustomUrlOrRegionSupport: false,
69
+ turboModule: true
70
+ };
71
+ class FirebaseAuthModule extends FirebaseModule {
72
+ constructor(app, config, customUrlOrRegion) {
73
+ super(app, config, customUrlOrRegion);
74
+ this._user = null;
75
+ this._settings = null;
76
+ this._authResult = false;
77
+ this._languageCode = this.native.APP_LANGUAGE[this.app.name] ?? '';
78
+ this._tenantId = null;
79
+ this._projectPasswordPolicy = null;
80
+ this._tenantPasswordPolicies = {};
81
+ this._emulatorConfig = null;
82
+ this._authStateReadyPromise = null;
83
+ this._beforeAuthStateChangedCallbacks = [];
84
+ if (!this.languageCode) {
85
+ this._languageCode = this.native.APP_LANGUAGE['[DEFAULT]'] ?? '';
86
+ }
87
+ const initialUser = this.native.APP_USER[this.app.name];
88
+ if (initialUser) {
89
+ this._setUser(initialUser);
90
+ }
91
+ this.emitter.addListener(this.eventNameForApp('auth_state_changed'), event => {
92
+ const authEvent = event;
93
+ void this._handleAuthStateChanged(authEvent.user);
94
+ });
95
+ this.emitter.addListener(this.eventNameForApp('phone_auth_state_changed'), event => {
96
+ const phoneAuthEvent = event;
97
+ const eventKey = `phone:auth:${phoneAuthEvent.requestKey}:${phoneAuthEvent.type}`;
98
+ this.emitter.emit(eventKey, phoneAuthEvent.state);
99
+ });
100
+ this.emitter.addListener(this.eventNameForApp('auth_id_token_changed'), event => {
101
+ const authEvent = event;
102
+ this._setUser(authEvent.user);
103
+ this.emitter.emit(this.eventNameForApp('onIdTokenChanged'), this._user);
104
+ });
105
+ this.native.addAuthStateListener();
106
+ this.native.addIdTokenListener();
107
+
108
+ // custom authDomain in only available from App's FirebaseOptions,
109
+ // but we need it in Auth if it exists. During app configuration we store
110
+ // mappings from app name to authDomain, this auth constructor
111
+ // is a reasonable time to use the mapping and set it into auth natively
112
+ if (!isOther) {
113
+ // Only supported on native platforms
114
+ this.native.configureAuthDomain();
115
+ }
116
+ }
117
+ get languageCode() {
118
+ return this._languageCode;
119
+ }
120
+ set languageCode(code) {
121
+ // For modular API, not recommended to set languageCode directly as it should be set in the native SDKs first
122
+ if (!isString(code) && !isNull(code)) {
123
+ throw new Error("firebase.auth().languageCode = (*) expected 'languageCode' to be a string or null value");
124
+ }
125
+ // as this is a setter, we can't use async/await. So we set it first so it is available immediately
126
+ if (code === null) {
127
+ this._languageCode = this.native.APP_LANGUAGE[this.app.name] ?? '';
128
+ if (!this.languageCode) {
129
+ this._languageCode = this.native.APP_LANGUAGE['[DEFAULT]'] ?? '';
130
+ }
131
+ } else {
132
+ this._languageCode = code;
133
+ }
134
+ // This sets it natively
135
+ void this.setLanguageCode(code);
136
+ }
137
+ get config() {
138
+ // Native iOS/Android Firebase Auth SDKs do not expose the firebase-js-sdk config object.
139
+ return {};
140
+ }
141
+ get tenantId() {
142
+ return this._tenantId;
143
+ }
144
+ set tenantId(tenantId) {
145
+ void this.setTenantId(tenantId);
146
+ }
147
+ get emulatorConfig() {
148
+ return this._emulatorConfig;
149
+ }
150
+ authStateReady() {
151
+ if (this._authResult) {
152
+ return Promise.resolve();
153
+ }
154
+ if (!this._authStateReadyPromise) {
155
+ this._authStateReadyPromise = new Promise(resolve => {
156
+ const unsubscribe = this.onAuthStateChanged(() => {
157
+ if (this._authResult) {
158
+ unsubscribe();
159
+ resolve();
160
+ }
161
+ });
162
+ if (this._authResult) {
163
+ unsubscribe();
164
+ resolve();
165
+ }
166
+ });
167
+ }
168
+ return this._authStateReadyPromise;
169
+ }
170
+ beforeAuthStateChanged(callback, onAbort) {
171
+ const entry = {
172
+ callback,
173
+ onAbort
174
+ };
175
+ this._beforeAuthStateChangedCallbacks.push(entry);
176
+ return () => {
177
+ const index = this._beforeAuthStateChangedCallbacks.indexOf(entry);
178
+ if (index >= 0) {
179
+ this._beforeAuthStateChangedCallbacks.splice(index, 1);
180
+ }
181
+ };
182
+ }
183
+ async updateCurrentUser(user) {
184
+ if (user === null) {
185
+ await this.signOut();
186
+ return;
187
+ }
188
+ const userInternal = user;
189
+ if (!userInternal._auth || userInternal._auth !== this) {
190
+ throw new Error("firebase.auth().updateCurrentUser() expected 'user' to be an Auth instance from the same Firebase App");
191
+ }
192
+ if (!userInternal._user) {
193
+ throw new Error("firebase.auth().updateCurrentUser(*) expected 'user' to be a valid User");
194
+ }
195
+ this._setUser(userInternal._user);
196
+ }
197
+ async _handleAuthStateChanged(nativeUser) {
198
+ const pendingUser = nativeUser ? new UserClass(this, nativeUser) : null;
199
+ for (const {
200
+ callback,
201
+ onAbort
202
+ } of [...this._beforeAuthStateChangedCallbacks]) {
203
+ try {
204
+ await callback(pendingUser);
205
+ } catch {
206
+ onAbort?.();
207
+ return;
208
+ }
209
+ }
210
+ this._setUser(nativeUser);
211
+ this.emitter.emit(this.eventNameForApp('onAuthStateChanged'), this._user);
212
+ }
213
+ get settings() {
214
+ if (!this._settings) {
215
+ this._settings = new Settings(this);
216
+ }
217
+ return this._settings;
218
+ }
219
+ get currentUser() {
220
+ return this._user;
221
+ }
222
+ _setUser(user) {
223
+ this._user = user ? new UserClass(this, user) : null;
224
+ this._authResult = true;
225
+ this.emitter.emit(this.eventNameForApp('onUserChanged'), this._user);
226
+ return this._user;
227
+ }
228
+ _setUserCredential(userCredential) {
229
+ const user = new UserClass(this, userCredential.user);
230
+ this._user = user;
231
+ this._authResult = true;
232
+ this.emitter.emit(this.eventNameForApp('onUserChanged'), this._user);
233
+ return {
234
+ additionalUserInfo: userCredential.additionalUserInfo,
235
+ user
236
+ };
237
+ }
238
+ async setLanguageCode(code) {
239
+ if (!isString(code) && !isNull(code)) {
240
+ throw new Error("firebase.auth().setLanguageCode(*) expected 'languageCode' to be a string or null value");
241
+ }
242
+ await this.native.setLanguageCode(code);
243
+ if (code === null) {
244
+ this._languageCode = this.native.APP_LANGUAGE[this.app.name] ?? '';
245
+ if (!this.languageCode) {
246
+ this._languageCode = this.native.APP_LANGUAGE['[DEFAULT]'] ?? '';
247
+ }
248
+ } else {
249
+ this._languageCode = code;
250
+ }
251
+ }
252
+ async setTenantId(tenantId) {
253
+ if (!isString(tenantId) && !isNull(tenantId)) {
254
+ throw new Error("firebase.auth().setTenantId(*) expected 'tenantId' to be a string");
255
+ }
256
+ await this.native.setTenantId(tenantId);
257
+ this._tenantId = tenantId;
258
+ }
259
+ onAuthStateChanged(listenerOrObserver) {
260
+ const listener = parseListenerOrObserver(listenerOrObserver);
261
+ const subscription = this.emitter.addListener(this.eventNameForApp('onAuthStateChanged'), listener);
262
+ if (this._authResult) {
263
+ Promise.resolve().then(() => {
264
+ listener(this._user || null);
265
+ });
266
+ }
267
+ return () => subscription.remove();
268
+ }
269
+ onIdTokenChanged(listenerOrObserver) {
270
+ const listener = parseListenerOrObserver(listenerOrObserver);
271
+ const subscription = this.emitter.addListener(this.eventNameForApp('onIdTokenChanged'), listener);
272
+ if (this._authResult) {
273
+ Promise.resolve().then(() => {
274
+ listener(this._user || null);
275
+ });
276
+ }
277
+ return () => subscription.remove();
278
+ }
279
+ onUserChanged(listenerOrObserver) {
280
+ const listener = parseListenerOrObserver(listenerOrObserver);
281
+ const subscription = this.emitter.addListener(this.eventNameForApp('onUserChanged'), listener);
282
+ if (this._authResult) {
283
+ Promise.resolve().then(() => {
284
+ listener(this._user || null);
285
+ });
286
+ }
287
+ return () => {
288
+ subscription.remove();
289
+ };
290
+ }
291
+ signOut() {
292
+ return this.native.signOut().then(() => {
293
+ this._setUser(null);
294
+ });
295
+ }
296
+ signInAnonymously() {
297
+ return this.native.signInAnonymously().then(userCredential => this._setUserCredential(userCredential));
298
+ }
299
+ signInWithPhoneNumber(phoneNumber, forceResend) {
300
+ return this.native.signInWithPhoneNumber(phoneNumber, forceResend || false).then(result => new ConfirmationResultClass(this, result.verificationId));
301
+ }
302
+ verifyPhoneNumber(phoneNumber, autoVerifyTimeoutOrForceResend, forceResend) {
303
+ let _forceResend = forceResend;
304
+ let _autoVerifyTimeout = 60;
305
+ if (isBoolean(autoVerifyTimeoutOrForceResend)) {
306
+ _forceResend = autoVerifyTimeoutOrForceResend;
307
+ } else {
308
+ _autoVerifyTimeout = autoVerifyTimeoutOrForceResend;
309
+ }
310
+ return new PhoneAuthListenerClass(this, phoneNumber, _autoVerifyTimeout, _forceResend);
311
+ }
312
+ verifyPhoneNumberWithMultiFactorInfo(multiFactorHint, session) {
313
+ return this.native.verifyPhoneNumberWithMultiFactorInfo(multiFactorHint.uid, session);
314
+ }
315
+ verifyPhoneNumberForMultiFactor(phoneInfoOptions) {
316
+ const {
317
+ phoneNumber,
318
+ session
319
+ } = phoneInfoOptions;
320
+ return this.native.verifyPhoneNumberForMultiFactor(phoneNumber, session);
321
+ }
322
+ resolveMultiFactorSignIn(session, verificationId, verificationCode) {
323
+ return this.native.resolveMultiFactorSignIn(session, verificationId, verificationCode).then(userCredential => {
324
+ return this._setUserCredential(userCredential);
325
+ });
326
+ }
327
+ resolveTotpSignIn(session, uid, totpSecret) {
328
+ return this.native.resolveTotpSignIn(session, uid, totpSecret).then(userCredential => {
329
+ return this._setUserCredential(userCredential);
330
+ });
331
+ }
332
+ createUserWithEmailAndPassword(email, password) {
333
+ return this.native.createUserWithEmailAndPassword(email, password).then(userCredential => this._setUserCredential(userCredential))
334
+ /* istanbul ignore next - native error handling cannot be unit tested */.catch(error => {
335
+ if (error.code === 'auth/password-does-not-meet-requirements') {
336
+ return this._recachePasswordPolicy().catch(() => {
337
+ // Silently ignore recache failures - the original error matters more
338
+ }).then(() => {
339
+ throw error;
340
+ });
341
+ }
342
+ throw error;
343
+ });
344
+ }
345
+ signInWithEmailAndPassword(email, password) {
346
+ return this.native.signInWithEmailAndPassword(email, password).then(userCredential => this._setUserCredential(userCredential))
347
+ /* istanbul ignore next - native error handling cannot be unit tested */.catch(error => {
348
+ if (error.code === 'auth/password-does-not-meet-requirements') {
349
+ return this._recachePasswordPolicy().catch(() => {
350
+ // Silently ignore recache failures - the original error matters more
351
+ }).then(() => {
352
+ throw error;
353
+ });
354
+ }
355
+ throw error;
356
+ });
357
+ }
358
+ signInWithCustomToken(customToken) {
359
+ return this.native.signInWithCustomToken(customToken).then(userCredential => this._setUserCredential(userCredential));
360
+ }
361
+ signInWithCredential(credential) {
362
+ return this.native.signInWithCredential(credential.providerId, credential.token, credential.secret).then(userCredential => this._setUserCredential(userCredential));
363
+ }
364
+ revokeToken(authorizationCode) {
365
+ return this.native.revokeToken(authorizationCode);
366
+ }
367
+ sendPasswordResetEmail(email, actionCodeSettings = null) {
368
+ return this.native.sendPasswordResetEmail(email, actionCodeSettings);
369
+ }
370
+ _resolveActionCodeSettings(actionCodeSettings) {
371
+ if (actionCodeSettings && isString(actionCodeSettings.url)) {
372
+ return actionCodeSettings;
373
+ }
374
+ const authDomain = this.app.options.authDomain;
375
+ let url = 'https://localhost';
376
+ if (authDomain && isString(authDomain)) {
377
+ url = isValidUrl(authDomain) ? authDomain : `https://${authDomain}`;
378
+ }
379
+ return {
380
+ ...(actionCodeSettings ?? {}),
381
+ url,
382
+ handleCodeInApp: actionCodeSettings?.handleCodeInApp ?? true
383
+ };
384
+ }
385
+ sendSignInLinkToEmail(email, actionCodeSettings) {
386
+ return this.native.sendSignInLinkToEmail(email, this._resolveActionCodeSettings(actionCodeSettings));
387
+ }
388
+ isSignInWithEmailLink(emailLink) {
389
+ return this.native.isSignInWithEmailLink(emailLink);
390
+ }
391
+ signInWithEmailLink(email, emailLink) {
392
+ return this.native.signInWithEmailLink(email, emailLink ?? '').then(userCredential => this._setUserCredential(userCredential));
393
+ }
394
+ confirmPasswordReset(code, newPassword) {
395
+ return this.native.confirmPasswordReset(code, newPassword)
396
+ /* istanbul ignore next - native error handling cannot be unit tested */.catch(error => {
397
+ if (error.code === 'auth/password-does-not-meet-requirements') {
398
+ return this._recachePasswordPolicy().catch(() => {
399
+ // Silently ignore recache failures - the original error matters more
400
+ }).then(() => {
401
+ throw error;
402
+ });
403
+ }
404
+ throw error;
405
+ });
406
+ }
407
+ applyActionCode(code) {
408
+ return this.native.applyActionCode(code).then(user => {
409
+ this._setUser(user);
410
+ });
411
+ }
412
+ checkActionCode(code) {
413
+ return this.native.checkActionCode(code);
414
+ }
415
+ fetchSignInMethodsForEmail(email) {
416
+ return this.native.fetchSignInMethodsForEmail(email);
417
+ }
418
+ verifyPasswordResetCode(code) {
419
+ return this.native.verifyPasswordResetCode(code);
420
+ }
421
+ useUserAccessGroup(userAccessGroup) {
422
+ if (isAndroid) {
423
+ return Promise.resolve();
424
+ }
425
+ return this.native.useUserAccessGroup(userAccessGroup).then(() => undefined);
426
+ }
427
+ getRedirectResult() {
428
+ throw new Error('firebase.auth().getRedirectResult() is unsupported by the native Firebase SDKs.');
429
+ }
430
+ setPersistence() {
431
+ throw new Error('firebase.auth().setPersistence() is unsupported by the native Firebase SDKs.');
432
+ }
433
+ signInWithPopup(provider) {
434
+ return this.native.signInWithProvider(provider.toObject()).then(userCredential => this._setUserCredential(userCredential));
435
+ }
436
+ signInWithRedirect(provider) {
437
+ return this.native.signInWithProvider(provider.toObject()).then(userCredential => this._setUserCredential(userCredential));
438
+ }
439
+
440
+ // firebase issue - https://github.com/invertase/react-native-firebase/pull/655#issuecomment-349904680
441
+ useDeviceLanguage() {
442
+ throw new Error('firebase.auth().useDeviceLanguage() is unsupported by the native Firebase SDKs.');
443
+ }
444
+ useEmulator(url, options) {
445
+ if (!url || !isString(url) || !isValidUrl(url)) {
446
+ throw new Error('firebase.auth().useEmulator() takes a non-empty string URL');
447
+ }
448
+ let _url = url;
449
+ const androidBypassEmulatorUrlRemap = typeof this.firebaseJson.android_bypass_emulator_url_remap === 'boolean' && this.firebaseJson.android_bypass_emulator_url_remap;
450
+ if (!androidBypassEmulatorUrlRemap && isAndroid && _url) {
451
+ if (_url.startsWith('http://localhost')) {
452
+ _url = _url.replace('http://localhost', 'http://10.0.2.2');
453
+ // eslint-disable-next-line no-console
454
+ console.log('Mapping auth host "localhost" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.');
455
+ }
456
+ if (_url.startsWith('http://127.0.0.1')) {
457
+ _url = _url.replace('http://127.0.0.1', 'http://10.0.2.2');
458
+ // eslint-disable-next-line no-console
459
+ console.log('Mapping auth host "127.0.0.1" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.');
460
+ }
461
+ }
462
+
463
+ // Native calls take the host and port split out
464
+ const hostPortRegex = /^http:\/\/([\w\d-.]+):(\d+)$/;
465
+ const urlMatches = _url.match(hostPortRegex);
466
+ if (!urlMatches) {
467
+ throw new Error('firebase.auth().useEmulator() unable to parse host and port from URL');
468
+ }
469
+ const host = urlMatches[1];
470
+ const portString = urlMatches[2];
471
+ if (!host) {
472
+ throw new Error('firebase.auth().useEmulator() unable to parse host from URL');
473
+ }
474
+ const port = portString ? parseInt(portString, 10) : undefined;
475
+ this._emulatorConfig = {
476
+ protocol: 'http',
477
+ host,
478
+ port: port ?? null,
479
+ options: {
480
+ disableWarnings: options?.disableWarnings ?? false
481
+ }
482
+ };
483
+ this.native.useEmulator(host, port);
484
+ // @ts-ignore - undocumented return, useful for unit testing
485
+ return [host, port];
486
+ }
487
+ getMultiFactorResolver(error) {
488
+ return createMultiFactorResolver(this, error);
489
+ }
490
+ multiFactor(user) {
491
+ if (!this.currentUser || user.uid !== this.currentUser.uid) {
492
+ throw new Error('firebase.auth().multiFactor() only operates on currentUser');
493
+ }
494
+ return new MultiFactorUserModule(this, user);
495
+ }
496
+ getCustomAuthDomain() {
497
+ return this.native.getCustomAuthDomain();
498
+ }
499
+ }
500
+
501
+ // Apply password policy mixin to FirebaseAuthModule
502
+ Object.assign(FirebaseAuthModule.prototype, PasswordPolicyMixin);
503
+ export { AppleAuthProvider, EmailAuthProvider, FacebookAuthProvider, GithubAuthProvider, GoogleAuthProvider, OAuthProvider, OIDCAuthProvider, PhoneAuthProvider, PhoneAuthState, PhoneMultiFactorGenerator, TotpMultiFactorGenerator, TotpSecret, TwitterAuthProvider, ActionCodeOperation, FactorId, OperationType, ProviderId, SignInMethod };
504
+ function getAuthInternal(auth) {
505
+ return auth;
506
+ }
507
+ function getUserInternal(user) {
508
+ return user;
509
+ }
510
+ function normalizeAdditionalUserInfo(info) {
511
+ return {
512
+ ...info,
513
+ isNewUser: Boolean(info.isNewUser),
514
+ profile: info.profile ?? null,
515
+ providerId: info.providerId ?? null,
516
+ username: info.username ?? null
517
+ };
518
+ }
519
+ function normalizeUserCredential(userCredential, overrides = {}) {
520
+ const normalizedUserCredential = {
521
+ user: userCredential.user,
522
+ providerId: overrides.providerId ?? userCredential.providerId ?? userCredential.additionalUserInfo?.providerId ?? null,
523
+ operationType: overrides.operationType ?? userCredential.operationType ?? OperationType.SIGN_IN
524
+ };
525
+ if (userCredential.additionalUserInfo) {
526
+ normalizedUserCredential.additionalUserInfo = normalizeAdditionalUserInfo(userCredential.additionalUserInfo);
527
+ }
528
+ return normalizedUserCredential;
529
+ }
530
+ function normalizeMultiFactorInfo(info) {
531
+ const normalizedInfo = {
532
+ uid: info.uid,
533
+ displayName: info.displayName ?? null,
534
+ enrollmentTime: info.enrollmentTime,
535
+ factorId: info.factorId
536
+ };
537
+ if ('phoneNumber' in info) {
538
+ return {
539
+ ...normalizedInfo,
540
+ phoneNumber: info.phoneNumber
541
+ };
542
+ }
543
+ return normalizedInfo;
544
+ }
545
+ function normalizeActionCodeInfo(actionCodeInfo) {
546
+ const data = actionCodeInfo.data ?? {};
547
+ return {
548
+ data: {
549
+ email: data.email ?? null,
550
+ multiFactorInfo: 'multiFactorInfo' in data && data.multiFactorInfo ? normalizeMultiFactorInfo(data.multiFactorInfo) : null,
551
+ previousEmail: ('previousEmail' in data ? data.previousEmail : undefined) ?? ('fromEmail' in data ? data.fromEmail : undefined) ?? null
552
+ },
553
+ operation: actionCodeInfo.operation
554
+ };
555
+ }
556
+ function normalizeConfirmationResult(confirmationResult) {
557
+ if (!confirmationResult.verificationId) {
558
+ throw new Error('signInWithPhoneNumber() did not return a verificationId.');
559
+ }
560
+ return {
561
+ verificationId: confirmationResult.verificationId,
562
+ async confirm(verificationCode) {
563
+ const userCredential = await confirmationResult.confirm(verificationCode);
564
+ if (!userCredential) {
565
+ throw new Error('signInWithPhoneNumber().confirm() returned no user credential.');
566
+ }
567
+ return normalizeUserCredential(userCredential, {
568
+ providerId: ProviderId.PHONE,
569
+ operationType: OperationType.SIGN_IN
570
+ });
571
+ }
572
+ };
573
+ }
574
+ function normalizeMultiFactorResolver(resolver) {
575
+ return {
576
+ hints: resolver.hints.map(normalizeMultiFactorInfo),
577
+ session: resolver.session,
578
+ async resolveSignIn(assertion) {
579
+ return normalizeUserCredential(await resolver.resolveSignIn(assertion), {
580
+ providerId: assertion.factorId === FactorId.PHONE ? ProviderId.PHONE : null,
581
+ operationType: OperationType.SIGN_IN
582
+ });
583
+ }
584
+ };
585
+ }
586
+ function normalizeMultiFactorUser(multiFactorUser) {
587
+ return {
588
+ enrolledFactors: multiFactorUser.enrolledFactors.map(normalizeMultiFactorInfo),
589
+ getSession: () => multiFactorUser.getSession(),
590
+ enroll: (assertion, displayName) => multiFactorUser.enroll(assertion, displayName),
591
+ unenroll: option => multiFactorUser.unenroll(option)
592
+ };
593
+ }
594
+ function normalizeAuthListener(nextOrObserver) {
595
+ if (typeof nextOrObserver === 'function') {
596
+ return nextOrObserver;
597
+ }
598
+ if (typeof nextOrObserver.next !== 'function') {
599
+ return {
600
+ next: () => {}
601
+ };
602
+ }
603
+ return nextOrObserver;
604
+ }
605
+ function callAuthMethod(auth, method, ...args) {
606
+ return method.call(auth, ...args);
607
+ }
608
+ function callUserMethod(user, method, ...args) {
609
+ return method.call(user, ...args);
610
+ }
611
+
612
+ /**
613
+ * Returns the Auth instance associated with the provided FirebaseApp.
614
+ *
615
+ * @param app - The Firebase app instance. Defaults to the default app.
616
+ */
617
+ export function getAuth(app) {
618
+ return getOrCreateModularInstance(FirebaseAuthModule, config, app);
619
+ }
620
+
621
+ /**
622
+ * This function allows more control over the Auth instance than getAuth().
623
+ *
624
+ * @param app - The Firebase app to initialize Auth for.
625
+ * @param _deps - Optional firebase-js-sdk dependency bag.
626
+ *
627
+ * @remarks
628
+ * The optional `deps` argument exists for firebase-js-sdk API parity. React Native Firebase
629
+ * ignores persistence, popup redirect resolver, and error-map dependencies because native
630
+ * iOS/Android SDKs manage auth state and do not support the web-only persistence stack.
631
+ * `initializeAuth()` returns the same shared Auth instance as {@link getAuth}.
632
+ */
633
+ export function initializeAuth(app, _deps) {
634
+ return getAuth(app);
635
+ }
636
+
637
+ /**
638
+ * Applies an out-of-band email action code (for example from a password reset or email verification link).
639
+ */
640
+ export function applyActionCode(auth, oobCode) {
641
+ const authInternal = getAuthInternal(auth);
642
+ return callAuthMethod(authInternal, authInternal.applyActionCode, oobCode);
643
+ }
644
+
645
+ /**
646
+ * Registers a callback to run before an auth state change is committed.
647
+ *
648
+ * @returns An unsubscribe function.
649
+ */
650
+ export function beforeAuthStateChanged(auth, callback, onAbort) {
651
+ const authInternal = getAuthInternal(auth);
652
+ return authInternal.beforeAuthStateChanged(callback, onAbort);
653
+ }
654
+
655
+ /**
656
+ * Checks the validity of an out-of-band email action code and returns metadata about the pending operation.
657
+ *
658
+ * @remarks React Native Firebase normalizes native results toward firebase-js-sdk shapes, including mapping
659
+ * `fromEmail` to `previousEmail` and coercing multi-factor info objects.
660
+ */
661
+ export function checkActionCode(auth, oobCode) {
662
+ const authInternal = getAuthInternal(auth);
663
+ return callAuthMethod(authInternal, authInternal.checkActionCode, oobCode).then(normalizeActionCodeInfo);
664
+ }
665
+
666
+ /**
667
+ * Confirms a password reset using the out-of-band code from the reset email.
668
+ */
669
+ export function confirmPasswordReset(auth, oobCode, newPassword) {
670
+ const authInternal = getAuthInternal(auth);
671
+ return callAuthMethod(authInternal, authInternal.confirmPasswordReset, oobCode, newPassword);
672
+ }
673
+
674
+ /**
675
+ * Connects the Auth instance to the Auth emulator.
676
+ *
677
+ * @remarks Delegates to the native `useEmulator` bridge. Accepts the firebase-js-sdk
678
+ * `options.disableWarnings` flag for {@link Auth.emulatorConfig} parity. On web, that flag
679
+ * suppresses the emulator DOM warning banner; native iOS/Android SDKs do not surface that banner,
680
+ * so the value is recorded on `auth.emulatorConfig.options` only. When `options` is provided,
681
+ * `disableWarnings` is required (matching firebase-js-sdk).
682
+ */
683
+ export function connectAuthEmulator(auth, url, options) {
684
+ const authInternal = getAuthInternal(auth);
685
+ callAuthMethod(authInternal, authInternal.useEmulator, url, options);
686
+ }
687
+
688
+ /**
689
+ * Creates a new user with an email address and password.
690
+ *
691
+ * @remarks Returned {@link UserCredential} objects include top-level `providerId` and `operationType`
692
+ * fields. `additionalUserInfo`, when present, is attached as a non-enumerable property.
693
+ */
694
+ export function createUserWithEmailAndPassword(auth, email, password) {
695
+ const authInternal = getAuthInternal(auth);
696
+ return callAuthMethod(authInternal, authInternal.createUserWithEmailAndPassword, email, password).then(userCredential => normalizeUserCredential(userCredential, {
697
+ operationType: OperationType.SIGN_IN
698
+ }));
699
+ }
700
+
701
+ /**
702
+ * Fetches the sign-in methods available for the given email address.
703
+ */
704
+ export function fetchSignInMethodsForEmail(auth, email) {
705
+ const authInternal = getAuthInternal(auth);
706
+ return callAuthMethod(authInternal, authInternal.fetchSignInMethodsForEmail, email);
707
+ }
708
+
709
+ /**
710
+ * Extracts a {@link MultiFactorResolver} from a {@link MultiFactorError}.
711
+ *
712
+ * @throws If the error does not contain resolver hints.
713
+ */
714
+ export function getMultiFactorResolver(auth, error) {
715
+ const authInternal = getAuthInternal(auth);
716
+ const resolver = callAuthMethod(authInternal, authInternal.getMultiFactorResolver, error);
717
+ if (!resolver) {
718
+ throw new Error('The provided auth error did not contain a multi-factor resolver.');
719
+ }
720
+ return normalizeMultiFactorResolver(resolver);
721
+ }
722
+
723
+ /**
724
+ * Returns the redirect sign-in result after a browser redirect flow completes.
725
+ *
726
+ * @remarks
727
+ * **Not supported on React Native Firebase.** Always throws synchronously because native provider
728
+ * flows do not use the browser redirect contract from the firebase-js-sdk.
729
+ */
730
+ export function getRedirectResult(_auth, _resolver) {
731
+ throw new Error('getRedirectResult is unsupported by the native Firebase SDKs.');
732
+ }
733
+
734
+ /**
735
+ * Checks whether an email link is a valid sign-in with email link URL.
736
+ *
737
+ */
738
+ export function isSignInWithEmailLink(auth, emailLink) {
739
+ const authInternal = getAuthInternal(auth);
740
+ return callAuthMethod(authInternal, authInternal.isSignInWithEmailLink, emailLink);
741
+ }
742
+
743
+ /**
744
+ * Subscribes to auth state changes for the given Auth instance.
745
+ *
746
+ * @returns An unsubscribe function.
747
+ *
748
+ * @remarks The legacy `error` and `completed` callback overload exists for firebase-js-sdk API parity.
749
+ * Native auth listeners never invoke separate error or completed callbacks.
750
+ */
751
+ export function onAuthStateChanged(auth, nextOrObserver, _error, _completed) {
752
+ // The legacy callback overload exists for JS SDK compatibility, but native auth listeners
753
+ // never invoke separate error/completed callbacks.
754
+ const authInternal = getAuthInternal(auth);
755
+ return callAuthMethod(authInternal, authInternal.onAuthStateChanged, normalizeAuthListener(nextOrObserver));
756
+ }
757
+
758
+ /**
759
+ * Subscribes to ID token changes for the given Auth instance.
760
+ *
761
+ * @returns An unsubscribe function.
762
+ *
763
+ * @remarks The legacy `error` and `completed` callback overload exists for firebase-js-sdk API parity.
764
+ * Native auth listeners never invoke separate error or completed callbacks.
765
+ */
766
+ export function onIdTokenChanged(auth, nextOrObserver, _error, _completed) {
767
+ // The legacy callback overload exists for JS SDK compatibility, but native auth listeners
768
+ // never invoke separate error/completed callbacks.
769
+ const authInternal = getAuthInternal(auth);
770
+ return callAuthMethod(authInternal, authInternal.onIdTokenChanged, normalizeAuthListener(nextOrObserver));
771
+ }
772
+
773
+ /**
774
+ * Revokes the given OAuth access token for the current user.
775
+ *
776
+ * @remarks
777
+ * **Web only.** Always throws synchronously on React Native Firebase.
778
+ */
779
+ export function revokeAccessToken(_auth, _token) {
780
+ throw new Error('revokeAccessToken() is only supported on Web');
781
+ }
782
+
783
+ /**
784
+ * Revokes a user's Sign in with Apple token.
785
+ *
786
+ * @remarks
787
+ * React Native Firebase-specific API required by Apple's account-deletion guidelines.
788
+ * **Supported on iOS** via the native `revokeTokenWithAuthorizationCode` bridge.
789
+ * On Android and Web the bridge resolves without performing revocation (no-op).
790
+ * Distinct from firebase-js-sdk {@link revokeAccessToken}, which revokes OAuth access tokens on Web only.
791
+ */
792
+ export function revokeToken(auth, authorizationCode) {
793
+ const authInternal = getAuthInternal(auth);
794
+ return callAuthMethod(authInternal, authInternal.revokeToken, authorizationCode);
795
+ }
796
+
797
+ /**
798
+ * Sends a password reset email to the given address.
799
+ */
800
+ export function sendPasswordResetEmail(auth, email, actionCodeSettings) {
801
+ const authInternal = getAuthInternal(auth);
802
+ return callAuthMethod(authInternal, authInternal.sendPasswordResetEmail, email, actionCodeSettings);
803
+ }
804
+
805
+ /**
806
+ * Sends a sign-in with email link to the given address.
807
+ *
808
+ * @remarks `actionCodeSettings` is required in the modular API (matching firebase-js-sdk).
809
+ * The namespaced `firebase.auth().sendSignInLinkToEmail(email, settings?)` API still supplies
810
+ * defaults when settings are omitted.
811
+ */
812
+ export function sendSignInLinkToEmail(auth, email, actionCodeSettings) {
813
+ const authInternal = getAuthInternal(auth);
814
+ return callAuthMethod(authInternal, authInternal.sendSignInLinkToEmail, email, actionCodeSettings);
815
+ }
816
+
817
+ /**
818
+ * Sets the persistence type for the Auth instance.
819
+ *
820
+ * @remarks
821
+ * **Not supported on React Native Firebase.** Always throws synchronously because auth state is
822
+ * managed by the native iOS/Android SDKs rather than the web persistence stack.
823
+ */
824
+ export function setPersistence(_auth, _persistence) {
825
+ throw new Error('setPersistence is unsupported by the native Firebase SDKs.');
826
+ }
827
+
828
+ /**
829
+ * Signs in anonymously.
830
+ */
831
+ export function signInAnonymously(auth) {
832
+ const authInternal = getAuthInternal(auth);
833
+ return callAuthMethod(authInternal, authInternal.signInAnonymously).then(userCredential => normalizeUserCredential(userCredential, {
834
+ operationType: OperationType.SIGN_IN
835
+ }));
836
+ }
837
+
838
+ /**
839
+ * Signs in with the given auth credential.
840
+ */
841
+ export function signInWithCredential(auth, credential) {
842
+ const authInternal = getAuthInternal(auth);
843
+ return callAuthMethod(authInternal, authInternal.signInWithCredential, credential).then(userCredential => normalizeUserCredential(userCredential, {
844
+ providerId: credential.providerId,
845
+ operationType: OperationType.SIGN_IN
846
+ }));
847
+ }
848
+
849
+ /**
850
+ * Signs in with a custom authentication token.
851
+ */
852
+ export function signInWithCustomToken(auth, customToken) {
853
+ const authInternal = getAuthInternal(auth);
854
+ return callAuthMethod(authInternal, authInternal.signInWithCustomToken, customToken).then(userCredential => normalizeUserCredential(userCredential, {
855
+ operationType: OperationType.SIGN_IN
856
+ }));
857
+ }
858
+
859
+ /**
860
+ * Signs in with an email address and password.
861
+ */
862
+ export function signInWithEmailAndPassword(auth, email, password) {
863
+ const authInternal = getAuthInternal(auth);
864
+ return callAuthMethod(authInternal, authInternal.signInWithEmailAndPassword, email, password).then(userCredential => normalizeUserCredential(userCredential, {
865
+ operationType: OperationType.SIGN_IN
866
+ }));
867
+ }
868
+
869
+ /**
870
+ * Signs in using an email and sign-in with email link.
871
+ *
872
+ * @remarks The `emailLink` argument is optional, matching firebase-js-sdk.
873
+ */
874
+ export function signInWithEmailLink(auth, email, emailLink) {
875
+ const authInternal = getAuthInternal(auth);
876
+ return callAuthMethod(authInternal, authInternal.signInWithEmailLink, email, emailLink).then(userCredential => normalizeUserCredential(userCredential, {
877
+ providerId: ProviderId.PASSWORD,
878
+ operationType: OperationType.SIGN_IN
879
+ }));
880
+ }
881
+
882
+ /**
883
+ * Signs in with a phone number and returns a confirmation result for SMS verification.
884
+ *
885
+ * @remarks
886
+ * Native SDKs own the phone verification flow. The optional `appVerifier` argument from the
887
+ * firebase-js-sdk is ignored. This modular API also does not accept RNFB's legacy `forceResend`
888
+ * argument — use {@link verifyPhoneNumber} for the native listener / force-resend flow instead.
889
+ */
890
+ export function signInWithPhoneNumber(auth, phoneNumber, _appVerifier) {
891
+ // Native SDKs own the verification flow, so the modular wrapper intentionally ignores the
892
+ // JS SDK's optional ApplicationVerifier and forwards only the phone number.
893
+ const authInternal = getAuthInternal(auth);
894
+ return callAuthMethod(authInternal, authInternal.signInWithPhoneNumber, phoneNumber).then(normalizeConfirmationResult);
895
+ }
896
+
897
+ /**
898
+ * Starts native phone number verification and returns a listener for verification events.
899
+ *
900
+ * @remarks React Native Firebase-specific API with no firebase-js-sdk equivalent. Use this for
901
+ * auto-verification, resend, and multi-step phone auth flows that require native callbacks.
902
+ */
903
+ export function verifyPhoneNumber(auth, phoneNumber, autoVerifyTimeoutOrForceResend, forceResend) {
904
+ const authInternal = getAuthInternal(auth);
905
+ return callAuthMethod(authInternal, authInternal.verifyPhoneNumber, phoneNumber, autoVerifyTimeoutOrForceResend, forceResend);
906
+ }
907
+
908
+ /**
909
+ * Signs in with the given provider using a native popup-style flow where supported.
910
+ */
911
+ export function signInWithPopup(auth, provider, _resolver) {
912
+ const authInternal = getAuthInternal(auth);
913
+ return callAuthMethod(authInternal, authInternal.signInWithPopup, provider).then(userCredential => normalizeUserCredential(userCredential, {
914
+ providerId: provider.providerId,
915
+ operationType: OperationType.SIGN_IN
916
+ }));
917
+ }
918
+
919
+ /**
920
+ * Signs in with the given provider using a redirect-style flow.
921
+ *
922
+ * @remarks On React Native Firebase, native provider flows complete immediately and resolve with a
923
+ * {@link UserCredential} instead of following the browser redirect contract used by the
924
+ * firebase-js-sdk (which resolves later via {@link getRedirectResult}).
925
+ */
926
+ export function signInWithRedirect(auth, provider, _resolver) {
927
+ // Native provider flows complete immediately and return a credential instead of following the
928
+ // browser redirect contract from the Firebase JS SDK.
929
+ const authInternal = getAuthInternal(auth);
930
+ return callAuthMethod(authInternal, authInternal.signInWithRedirect, provider).then(userCredential => normalizeUserCredential(userCredential, {
931
+ providerId: provider.providerId,
932
+ operationType: OperationType.SIGN_IN
933
+ }));
934
+ }
935
+
936
+ /**
937
+ * Signs out the current user for the given Auth instance.
938
+ */
939
+ export function signOut(auth) {
940
+ const authInternal = getAuthInternal(auth);
941
+ return callAuthMethod(authInternal, authInternal.signOut);
942
+ }
943
+
944
+ /**
945
+ * Updates the currently signed-in user on the Auth instance.
946
+ */
947
+ export function updateCurrentUser(auth, user) {
948
+ const authInternal = getAuthInternal(auth);
949
+ return callAuthMethod(authInternal, authInternal.updateCurrentUser, user);
950
+ }
951
+
952
+ /**
953
+ * Sets the Auth `languageCode` from the device locale.
954
+ *
955
+ * @remarks
956
+ * **Not supported on React Native Firebase.** Always throws synchronously. Set `auth.languageCode`
957
+ * directly or use {@link setLanguageCode}.
958
+ */
959
+ export function useDeviceLanguage(_auth) {
960
+ throw new Error('useDeviceLanguage is unsupported by the native Firebase SDKs');
961
+ }
962
+
963
+ /**
964
+ * Sets the Auth language code.
965
+ *
966
+ * @remarks React Native Firebase exposes this as a modular helper. The firebase-js-sdk only exposes
967
+ * the writable `auth.languageCode` property.
968
+ */
969
+ export function setLanguageCode(auth, languageCode) {
970
+ const authInternal = getAuthInternal(auth);
971
+ return callAuthMethod(authInternal, authInternal.setLanguageCode, languageCode);
972
+ }
973
+
974
+ /**
975
+ * Configures iOS keychain access group sharing for the Auth instance.
976
+ *
977
+ * @remarks **iOS only** React Native Firebase helper with no firebase-js-sdk equivalent.
978
+ * Enables sharing auth state across apps in the same access group (e.g. app extensions).
979
+ */
980
+ export function useUserAccessGroup(auth, userAccessGroup) {
981
+ const authInternal = getAuthInternal(auth);
982
+ return callAuthMethod(authInternal, authInternal.useUserAccessGroup, userAccessGroup).then(() => undefined);
983
+ }
984
+
985
+ /**
986
+ * Verifies a password reset code and returns the associated email address.
987
+ */
988
+ export function verifyPasswordResetCode(auth, code) {
989
+ const authInternal = getAuthInternal(auth);
990
+ return callAuthMethod(authInternal, authInternal.verifyPasswordResetCode, code);
991
+ }
992
+
993
+ /**
994
+ * Parses an email action link string.
995
+ *
996
+ * @param link - The email action link to parse.
997
+ * @returns The {@link ActionCodeURL} object, or `null` if the link is invalid.
998
+ *
999
+ * @remarks Pure URL parsing (ported from firebase-js-sdk). Works on all platforms without a native
1000
+ * bridge. See also {@link ActionCodeURL.parseLink}.
1001
+ */
1002
+ export function parseActionCodeURL(link) {
1003
+ return ActionCodeURL.parseLink(link);
1004
+ }
1005
+
1006
+ /**
1007
+ * Deletes the given user account.
1008
+ */
1009
+ export function deleteUser(user) {
1010
+ const userInternal = getUserInternal(user);
1011
+ return callUserMethod(userInternal, userInternal.delete);
1012
+ }
1013
+
1014
+ /**
1015
+ * Returns the current ID token for the user.
1016
+ */
1017
+ export function getIdToken(user, forceRefresh) {
1018
+ const userInternal = getUserInternal(user);
1019
+ return callUserMethod(userInternal, userInternal.getIdToken, forceRefresh);
1020
+ }
1021
+
1022
+ /**
1023
+ * Returns the decoded ID token result for the user.
1024
+ */
1025
+ export function getIdTokenResult(user, forceRefresh) {
1026
+ const userInternal = getUserInternal(user);
1027
+ return callUserMethod(userInternal, userInternal.getIdTokenResult, forceRefresh);
1028
+ }
1029
+
1030
+ /**
1031
+ * Links the user account with the given credential.
1032
+ */
1033
+ export function linkWithCredential(user, credential) {
1034
+ const userInternal = getUserInternal(user);
1035
+ return callUserMethod(userInternal, userInternal.linkWithCredential, credential).then(userCredential => normalizeUserCredential(userCredential, {
1036
+ providerId: credential.providerId,
1037
+ operationType: OperationType.LINK
1038
+ }));
1039
+ }
1040
+
1041
+ /**
1042
+ * Links the user account with a phone number using SMS verification.
1043
+ *
1044
+ * @remarks
1045
+ * **Not supported on React Native Firebase.** Always throws synchronously.
1046
+ */
1047
+ export function linkWithPhoneNumber(_user, _phoneNumber, _appVerifier) {
1048
+ throw new Error('linkWithPhoneNumber is unsupported by the native Firebase SDKs');
1049
+ }
1050
+
1051
+ /**
1052
+ * Links the user account with the given provider using a native popup-style flow where supported.
1053
+ */
1054
+ export function linkWithPopup(user, provider, _resolver) {
1055
+ const userInternal = getUserInternal(user);
1056
+ return callUserMethod(userInternal, userInternal.linkWithPopup, provider).then(userCredential => normalizeUserCredential(userCredential, {
1057
+ providerId: provider.providerId,
1058
+ operationType: OperationType.LINK
1059
+ }));
1060
+ }
1061
+
1062
+ /**
1063
+ * Links the user account with the given provider using a redirect-style flow.
1064
+ *
1065
+ * @remarks On React Native Firebase, native provider flows complete immediately and resolve with a
1066
+ * {@link UserCredential} instead of following the browser redirect contract used by the
1067
+ * firebase-js-sdk.
1068
+ */
1069
+ export function linkWithRedirect(user, provider, _resolver) {
1070
+ // Native provider flows complete immediately and return a credential instead of following the
1071
+ // browser redirect contract from the Firebase JS SDK.
1072
+ const userInternal = getUserInternal(user);
1073
+ return callUserMethod(userInternal, userInternal.linkWithRedirect, provider).then(userCredential => normalizeUserCredential(userCredential, {
1074
+ providerId: provider.providerId,
1075
+ operationType: OperationType.LINK
1076
+ }));
1077
+ }
1078
+
1079
+ /**
1080
+ * Returns the multi-factor interface for the given user.
1081
+ *
1082
+ * @remarks Uses the user's own Auth instance instead of always calling {@link getAuth}, which fixes
1083
+ * secondary Firebase app usage compared with earlier RNFB behavior.
1084
+ */
1085
+ export function multiFactor(user) {
1086
+ return normalizeMultiFactorUser(new MultiFactorUserModule(user._auth || getAuth(), user));
1087
+ }
1088
+
1089
+ /**
1090
+ * Reauthenticates the user with the given credential.
1091
+ */
1092
+ export function reauthenticateWithCredential(user, credential) {
1093
+ const userInternal = getUserInternal(user);
1094
+ return callUserMethod(userInternal, userInternal.reauthenticateWithCredential, credential).then(userCredential => normalizeUserCredential(userCredential, {
1095
+ providerId: credential.providerId,
1096
+ operationType: OperationType.REAUTHENTICATE
1097
+ }));
1098
+ }
1099
+
1100
+ /**
1101
+ * Reauthenticates the user with a phone number using SMS verification.
1102
+ *
1103
+ * @remarks
1104
+ * **Not supported on React Native Firebase.** Always throws synchronously.
1105
+ */
1106
+ export function reauthenticateWithPhoneNumber(_user, _phoneNumber, _appVerifier) {
1107
+ throw new Error('reauthenticateWithPhoneNumber is unsupported by the native Firebase SDKs');
1108
+ }
1109
+
1110
+ /**
1111
+ * Reauthenticates the user with the given provider using a native popup-style flow where supported.
1112
+ */
1113
+ export function reauthenticateWithPopup(user, provider, _resolver) {
1114
+ const userInternal = getUserInternal(user);
1115
+ return callUserMethod(userInternal, userInternal.reauthenticateWithPopup, provider).then(userCredential => normalizeUserCredential(userCredential, {
1116
+ providerId: provider.providerId,
1117
+ operationType: OperationType.REAUTHENTICATE
1118
+ }));
1119
+ }
1120
+
1121
+ /**
1122
+ * Reauthenticates the user with the given provider using a redirect-style flow.
1123
+ *
1124
+ * @remarks On React Native Firebase, native provider flows do not follow the browser redirect
1125
+ * contract. This resolves with `void` after the native flow completes instead of the
1126
+ * firebase-js-sdk `Promise<never>` signature used for unresolved browser redirects.
1127
+ */
1128
+ export function reauthenticateWithRedirect(user, provider, _resolver) {
1129
+ const userInternal = getUserInternal(user);
1130
+ return callUserMethod(userInternal, userInternal.reauthenticateWithRedirect, provider);
1131
+ }
1132
+
1133
+ /**
1134
+ * Reloads the user's profile data from the server.
1135
+ */
1136
+ export function reload(user) {
1137
+ const userInternal = getUserInternal(user);
1138
+ return callUserMethod(userInternal, userInternal.reload);
1139
+ }
1140
+
1141
+ /**
1142
+ * Sends an email verification message to the user.
1143
+ */
1144
+ export function sendEmailVerification(user, actionCodeSettings) {
1145
+ const userInternal = getUserInternal(user);
1146
+ return callUserMethod(userInternal, userInternal.sendEmailVerification, actionCodeSettings ?? undefined);
1147
+ }
1148
+
1149
+ /**
1150
+ * Unlinks a provider from the user account.
1151
+ */
1152
+ export function unlink(user, providerId) {
1153
+ const userInternal = getUserInternal(user);
1154
+ return callUserMethod(userInternal, userInternal.unlink, providerId);
1155
+ }
1156
+
1157
+ /**
1158
+ * Updates the user's email address.
1159
+ */
1160
+ export function updateEmail(user, newEmail) {
1161
+ const userInternal = getUserInternal(user);
1162
+ return callUserMethod(userInternal, userInternal.updateEmail, newEmail);
1163
+ }
1164
+
1165
+ /**
1166
+ * Updates the user's password.
1167
+ */
1168
+ export function updatePassword(user, newPassword) {
1169
+ const userInternal = getUserInternal(user);
1170
+ return callUserMethod(userInternal, userInternal.updatePassword, newPassword);
1171
+ }
1172
+
1173
+ /**
1174
+ * Updates the user's phone number using a phone auth credential.
1175
+ */
1176
+ export function updatePhoneNumber(user, credential) {
1177
+ const userInternal = getUserInternal(user);
1178
+ return callUserMethod(userInternal, userInternal.updatePhoneNumber, credential);
1179
+ }
1180
+
1181
+ /**
1182
+ * Updates the user's display name and/or photo URL.
1183
+ */
1184
+ export function updateProfile(user, profile) {
1185
+ const userInternal = getUserInternal(user);
1186
+ return callUserMethod(userInternal, userInternal.updateProfile, {
1187
+ displayName: profile.displayName,
1188
+ photoURL: profile.photoURL
1189
+ });
1190
+ }
1191
+
1192
+ /**
1193
+ * Sends a verification email to the new address before updating the user's email.
1194
+ */
1195
+ export function verifyBeforeUpdateEmail(user, newEmail, actionCodeSettings) {
1196
+ const userInternal = getUserInternal(user);
1197
+ return callUserMethod(userInternal, userInternal.verifyBeforeUpdateEmail, newEmail, actionCodeSettings ?? undefined);
1198
+ }
1199
+
1200
+ /**
1201
+ * Returns additional OAuth / federated sign-in information from a {@link UserCredential}.
1202
+ *
1203
+ * @remarks Returns firebase-js-sdk core fields plus any extra native keys copied from the bridge.
1204
+ */
1205
+ export function getAdditionalUserInfo(userCredential) {
1206
+ if (userCredential.additionalUserInfo) {
1207
+ return userCredential.additionalUserInfo;
1208
+ }
1209
+ const info = userCredential.additionalUserInfo;
1210
+ if (!info) {
1211
+ return null;
1212
+ }
1213
+ return normalizeAdditionalUserInfo(info);
1214
+ }
1215
+
1216
+ /**
1217
+ * Returns the configured custom auth domain for the Auth instance.
1218
+ *
1219
+ * @remarks React Native Firebase-specific helper with no firebase-js-sdk modular equivalent.
1220
+ * Reads the custom domain configured for the Firebase project through the native Auth SDK.
1221
+ */
1222
+ export function getCustomAuthDomain(auth) {
1223
+ const authInternal = getAuthInternal(auth);
1224
+ return callAuthMethod(authInternal, authInternal.getCustomAuthDomain);
1225
+ }
1226
+
1227
+ /**
1228
+ * Validates a password against the project's password policy.
1229
+ */
1230
+ export function validatePassword(auth, password) {
1231
+ if (!auth || !('app' in auth)) {
1232
+ throw new Error(`firebase.auth().validatePassword(*) 'auth' must be a valid Auth instance with an 'app' property`);
1233
+ }
1234
+ if (password === null || password === undefined) {
1235
+ throw new Error("firebase.auth().validatePassword(*) expected 'password' to be a non-null or a defined value.");
1236
+ }
1237
+ const authWithPasswordValidation = getAuthInternal(auth);
1238
+ return callAuthMethod(authWithPasswordValidation, authWithPasswordValidation.validatePassword, password);
1239
+ }
1240
+ export const SDK_VERSION = version;
24
1241
 
25
- // namespaced API
26
- export * from "./types/namespaced.js";
27
- export * from "./namespaced.js";
28
- export { default } from "./namespaced.js";
1242
+ // Register the interop module for non-native platforms.
1243
+ setReactNativeModule(nativeModuleName, fallBackModule);
29
1244
  //# sourceMappingURL=index.js.map