Open Arashadmin opened 2 months ago
Hey ho, just for your notice: we moved from react-native-firebase 19.2.2 packages to 19.3.0 and the error still exists.
👋 There is no way our library can create multiple users like this from a single API call, it's a direct API from JS to Native.
I'd suggest adding a logger in your handleSignup
method as it's likely some state updates a triggering this multiple times
Hi Mike,
Thanks for your answer and yes, I'd believe it too, that "there is no way" your library is creating multiple users and because it is a direct API Im a bit helpless to log what is happening behind the scenes.
When you take a look at the code samples that I attached, especially in the handleSignup function, it calls the Promise method "await auth.createAuthUser(email, password, name)" which then is this:
export const createAuthUser = async (
email: string,
password: string,
displayName: string
) => {
const isEmailExists = await ifEmailExists(email)
if (isEmailExists) {
throw new Error(
'Something went wrong. Please try again or contact the Audrey team.'
)
}
const cred = await auth()
.createUserWithEmailAndPassword(email, password)
.catch(rethrowAsErrorMessage)
await cred.user.updateProfile({displayName})
analytics.setUserName(displayName)
}
In here you can see, that we first call the createUser method and only if it does not throw an error (when the .catch does not catch anything), than we update the userName with cred.user.updateProfile({displayName}). In other words, if there would any errors be thrown (like email exists error), than our sentry system would catch this error (but doesn't).
So the error still occurs (only on production):
I tried everything to re-create this bug locally with the local firebase instance or on our staging environment but there it works fine.
For now I created a cronJob, that deletes duplicate user accounts, if it is not connected to a firebase document but this should only be temporary solution.
Hello @Arashadmin, have you been able to reproduce it reliably? We still cannot reproduce it on our end.
@Lyokone at least not on purpose. It only happens on production without any errors in our logs. But I'm wondering, if you even can build the project, with my provided code and if you go with the bare flow or with expo (as stated in our package.json).
The reason why I'm saying this is, because we have around 6 config plugins for our expo project, to be able to write into our AppDelegate or into our Android Manifest. I'm just wondering, if everything is configured correctly and if this error has anything to do with that since nearly each file is dedicated to a certain module of firebase. But on the other hand you do see our Android Manifest, that is a product of these config plugins, that get merged into the Manifest
How is it possible to create users with the same email address? I thought that Firebase Auth blocked creating users with the same email address i.e error code email-already-in-use
.
locally I can reproduce the "email-already-in-use" error code for 100%. Why this happens on production, I can not tell.
It might be this setting in Firebase console that allows the same email address but with different providers:
Note: you cannot create multiple accounts using same provider with same email address. See this google answer: https://support.google.com/firebase/answer/9134820
If you are seeing same email address with same provider, I would open a ticket with Firebase support and ask them to verify because it would be a bug on the Firebase server.
Hi Russel,
thanks for your reply.
This is exactly what we've checked:
I'll go and pursue the Firebase support thingy since we don't have any provider taking care of account creation - we only have basicAuth (email+pw) in combination with Firebase on our app.
@Arashadmin - as an FYI, Email/Password
is considered a provider. You can only have one email address for Email/Password
provider per user in Auth.
Thx Russel, I thought provider are things like facebook auth etc. :)
Issue
Describe your issue here
Summary: Our newly released Android app version creates multiple accounts on firebase authentication module when user signs up into our app via auth().createUserWithEmailAndPassword(email, password).
With our last Android release we've had some dependency updates shipped to production. Alongside other dependencies we also updated all firebase dependencies from 18.5.0 to 19.2.2.
Looking into the Firebase Authentication module, the same person has got for accounts with the same email address but with different User UIDs:![Screenshot 2024-06-21 at 10 43 10](https://github.com/invertase/react-native-firebase/assets/24981998/1f32b1e5-075d-4aa3-a285-00f6b5647625)
Project Files
Javascript
Click To Expand
This is our password screen component, where the createUserWithEmailAndPassword() method gets triggered. (name and email are collected in the previous screens). For you it is only important to know, that the user presses the CircularButton and invokes the "handleSignup" function, which invokes this wrapper method: await auth.createAuthUser(email, password, name): SignUpPassword.tsx: ```tsx import AsyncStorage from '@react-native-async-storage/async-storage' import React, {useEffect, useState} from 'react' import {Text, useWindowDimensions, View} from 'react-native' import CustomKeyboardAvoidingView from '../components/CustomKeboardAvoidingView' import * as auth from '../services/firebase/auth' import { CircularButton, Copy, NewScreenContainer, Spacer, TextInput, } from '../ui' const SignUpPassword = () => { const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [error, setError] = useState()
const [password, setPassword] = useState('')
const [isSigningUp, setIsSigningUp] = useState(false)
useEffect(() => {
const getName = async () => {
const userName = await AsyncStorage.getItem('name')
if (!userName) {
throw new Error(
'User name needs to be in Async Storage to go continue the sign up flow'
)
}
setName(userName)
}
const getEmail = async () => {
const userEmail = await AsyncStorage.getItem('email')
if (!userEmail) {
throw new Error(
'User email needs to be in Async Storage to go continue the sign up flow'
)
}
setEmail(userEmail)
}
getName()
getEmail()
}, [])
const handleSignup = async () => {
if (!email || !password) return
setIsSigningUp(true)
try {
await auth.createAuthUser(email, password, name)
AsyncStorage.removeItem('email')
AsyncStorage.removeItem('name')
} catch (error) {
setIsSigningUp(false)
setError((error as Error).message)
}
}
// fontScale is made for users who have to magnify the screen a lot
const fontScale = useWindowDimensions().fontScale
return (
1.7 : false}
>
Let's make it all yours!
Please set a password
{error && (
{error}
)}
)
}
export default SignUpPassword
```
These are the main functions in our auth.ts module which invoke the respective createUserWithEmailAndPassword method. (createAuthUser):
```ts
import auth, {FirebaseAuthTypes} from '@react-native-firebase/auth'
import {handleErrorSilently} from '../../utils/errorUtils'
import * as analytics from '../analytics'
export type AuthUser = FirebaseAuthTypes.User
// Copied from Firebase source because it's not exported :-(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type CallbackOrObserver any> = T | {next: T}
type AuthListenerCallback = FirebaseAuthTypes.AuthListenerCallback
const translateAuthError = (
error: FirebaseAuthTypes.NativeFirebaseAuthError
) => {
switch (error.code) {
case 'auth/invalid-email':
return 'Email address is not valid.'
case 'auth/user-disabled':
return 'User corresponding to the given email has been disabled.'
case 'auth/user-not-found':
return 'No user corresponding to the given email.'
case 'auth/wrong-password':
return 'Password is invalid for the given email, or account does not have set password.'
case 'auth/weak-password':
return 'Password is invalid. (Tip: Make sure you have at least 6 characters)'
case 'auth/email-already-in-use':
return 'Something went wrong. Please try again or contact the Audrey team.'
case 'auth/network-request-failed':
return "Couldn't reach the server. Is your phone connected to the internet?"
default: {
handleErrorSilently(error)
return 'Unexpected error, please try again'
}
}
}
const rethrowAsErrorMessage = (
error: FirebaseAuthTypes.NativeFirebaseAuthError
) => {
throw new Error(translateAuthError(error))
}
const ifEmailExists = async (email: string): Promise => {
const availableAuthMethods = await auth()
.fetchSignInMethodsForEmail(email)
.catch(rethrowAsErrorMessage)
return availableAuthMethods.length > 0
}
export const createAuthUser = async (
email: string,
password: string,
displayName: string
) => {
const isEmailExists = await ifEmailExists(email)
if (isEmailExists)
throw new Error(
'Something went wrong. Please try again or contact the Audrey team.'
)
const cred = await auth()
.createUserWithEmailAndPassword(email, password)
.catch(rethrowAsErrorMessage)
await cred.user.updateProfile({displayName})
analytics.setUserName(displayName)
}
export const sendPasswordResetEmail = (email: string) =>
auth().sendPasswordResetEmail(email).catch(rethrowAsErrorMessage)
export const signInWithEmailAndPassword = (email: string, password: string) =>
auth()
.signInWithEmailAndPassword(email, password)
.catch(rethrowAsErrorMessage)
```
In the "createAuthUser" function you can see, that the createUserWithEmailAndPassword method is invoked correctly and that nothing else happens alongside it (after the user account is created we just update the name and send the name also the the analytics package but that is something, that has no effect on this).
#### `package.json`:
```json
{
"name": "@audrey",
"main": "__generated__/AppEntry.js",
"version": "0.42.0",
"scripts": {
"start": "npx expo start --dev-client",
"clean": "npx expo prebuild --clean && rm -rf ios && rm -rf android",
"lint": "eslint --max-warnings=0 --ignore-path .gitignore --ext .js,.ts,.tsx --cache .",
"test": "jest",
"start-fb-emulator": "firebase emulators:start --only firestore,auth",
"postinstall": "expo-yarn-workspaces postinstall",
"release-manager": "cd ../tools/release-manager && yarn start",
"android": "npx expo run:android",
"ios": "npx expo run:ios"
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint"
]
},
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|@sentry/.*|mixpanel-react-native|nanoid)"
],
"setupFiles": [
"./jestSetup.js"
]
},
"dependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
"@contentful/rich-text-plain-text-renderer": "16.0.13",
"@expo-google-fonts/ibm-plex-sans": "0.2.3",
"@expo-google-fonts/ibm-plex-serif": "0.2.3",
"@gorhom/bottom-sheet": "4.6.3",
"@gorhom/portal": "1.0.14",
"@notionhq/client": "2.2.15",
"@portabletext/react-native": "1.1.10",
"@portabletext/types": "2.0.13",
"@react-native-async-storage/async-storage": "1.23.1",
"@react-native-community/masked-view": "0.1.11",
"@react-native-community/slider": "4.5.2",
"@react-native-firebase/analytics": "19.2.2",
"@react-native-firebase/app": "19.2.2",
"@react-native-firebase/app-check": "^19.2.2",
"@react-native-firebase/auth": "19.2.2",
"@react-native-firebase/dynamic-links": "19.2.2",
"@react-native-firebase/firestore": "19.2.2",
"@react-native-firebase/messaging": "19.2.2",
"@react-navigation/bottom-tabs": "6.5.20",
"@react-navigation/native": "6.1.17",
"@react-navigation/stack": "6.3.29",
"@segment/analytics-react-native": "^2.19.1",
"@segment/sovran-react-native": "^1.1.1",
"@sentry/react-native": "5.22.2",
"@types/lodash": "4.17.0",
"babel-plugin-module-resolver": "5.0.2",
"dotenv": "16.4.5",
"expo": "51.0.11",
"expo-application": "5.9.1",
"expo-build-properties": "0.12.1",
"expo-constants": "16.0.1",
"expo-dev-client": "4.0.14",
"expo-device": "6.0.2",
"expo-font": "12.0.5",
"expo-linear-gradient": "13.0.2",
"expo-linking": "6.3.1",
"expo-localization": "15.0.3",
"expo-network": "6.0.1",
"expo-notifications": "~0.28.3",
"expo-splash-screen": "~0.27.4",
"expo-status-bar": "1.12.1",
"expo-tracking-transparency": "~4.0.2",
"expo-updates": "0.25.14",
"immer": "9.0.21",
"jest": "29.7.0",
"jest-expo": "51.0.2",
"lodash-es": "4.17.21",
"md5": "2.3.0",
"mixpanel-react-native": "2.4.1",
"nanoid": "5.0.7",
"picosanity": "4.1.1",
"promise": "^8.3.0",
"react": "18.3.1",
"react-devtools-core": "5.2.0",
"react-dom": "18.3.1",
"react-native": "0.74.2",
"react-native-gesture-handler": "2.16.2",
"react-native-get-random-values": "~1.11.0",
"react-native-purchases": "7.27.1",
"react-native-reanimated": "3.10.1",
"react-native-safe-area-context": "4.10.1",
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
"react-native-svg-transformer": "1.3.0",
"react-native-track-player": "4.1.1",
"react-native-web": "0.19.10",
"react-native-webview": "13.10.2",
"react-native-youtube-iframe": "2.3.0",
"semver": "7.6.0",
"styled-components": "5.3.6",
"zustand": "4.5.2"
},
"devDependencies": {
"@babel/core": "7.24.4",
"@types/jest": "29.5.12",
"@types/md5": "2.3.5",
"@types/node-fetch": "2.6.11",
"@types/styled-components": "5.1.34",
"@types/styled-components-react-native": "5.2.5",
"@typescript-eslint/eslint-plugin": "7.7.1",
"@typescript-eslint/parser": "7.7.1",
"eslint": "8.57.0",
"eslint-plugin-jest": "28.5.0",
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-react-native": "4.1.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"expo-yarn-workspaces": "2.3.2",
"firebase-tools": "13.10.1",
"jest-file-snapshot": "0.5.0",
"lint-staged": "15.2.2",
"typescript": "5.3.3"
},
"author": "Audrey",
"private": true,
"license": "UNLICENSED"
}
```
#### `firebase.json` for react-native-firebase v6:
```json
{
"functions": {
"source": "functions",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"auth": {
"port": 9099,
"host": "0.0.0.0"
},
"functions": {
"port": 5001,
"host": "0.0.0.0"
},
"firestore": {
"port": 8080,
"host": "0.0.0.0"
},
"ui": {
"enabled": true
}
},
"react-native": {
"analytics_auto_collection_enabled": false,
"messaging_android_notification_color": "@color/black"
}
}
```
iOS
Click To Expand
#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby # N/A ``` #### `AppDelegate.m`: ```objc // N/A ```
Android
Click To Expand
#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = findProperty('android.buildToolsVersion') ?: '34.0.0' minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '23') compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '34') targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.23' ndkVersion = "26.1.10909125" } repositories { google() mavenCentral() } dependencies { classpath 'com.google.gms:google-services:4.3.3' classpath('com.android.tools.build:gradle') classpath('com.facebook.react:react-native-gradle-plugin') classpath('org.jetbrains.kotlin:kotlin-gradle-plugin') } } apply plugin: "com.facebook.react.rootproject" allprojects { repositories { maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) } maven { // Android JSC is installed from npm url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist')) } google() mavenCentral() maven { url 'https://www.jitpack.io' } } } ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy apply plugin: "com.android.application" apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath() /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. */ react { entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim()) reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc" codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() // Use Expo CLI to bundle the app, this ensures the Metro config // works correctly with Expo projects. cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim()) bundleCommand = "export:embed" /* Folders */ // The root of your project, i.e. where "package.json" lives. Default is '..' // root = file("../") // The folder where the react-native NPM package is. Default is ../node_modules/react-native // reactNativeDir = file("../node_modules/react-native") // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen // codegenDir = file("../node_modules/@react-native/codegen") /* Variants */ // The list of variants to that are debuggable. For those we're going to // skip the bundling of the JS bundle and the assets. By default is just 'debug'. // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. // debuggableVariants = ["liteDebug", "prodDebug"] /* Bundling */ // A list containing the node command and its flags. Default is just 'node'. // nodeExecutableAndArgs = ["node"] // // The path to the CLI configuration file. Default is empty. // bundleConfig = file(../rn-cli.config.js) // // The name of the generated asset file containing your JS bundle // bundleAssetName = "MyApplication.android.bundle" // // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' // entryFile = file("../js/MyApplication.android.js") // // A list of extra flags to pass to the 'bundle' commands. // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle // extraPackagerArgs = [] /* Hermes Commands */ // The hermes compiler command to run. By default it is 'hermesc' // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" // hermesFlags = ["-O", "-output-source-map"] } /** * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean() /** * The preferred build flavor of JavaScriptCore (JSC) * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' apply from: new File(["node", "--print", "require('path').dirname(require.resolve('@sentry/react-native/package.json'))"].execute().text.trim(), "sentry.gradle") android { ndkVersion rootProject.ext.ndkVersion buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion namespace 'com.audrey.audrey.dev' defaultConfig { applicationId 'com.audrey.audrey.dev' minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 4200 versionName "0.42.0" } signingConfigs { debug { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' } } buildTypes { debug { signingConfig signingConfigs.debug } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. signingConfig signingConfigs.debug shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } packagingOptions { jniLibs { useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false) } } } // Apply static values from `gradle.properties` to the `android.packagingOptions` // Accepts values in comma delimited lists, example: // android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini ["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop -> // Split option: 'foo,bar' -> ['foo', 'bar'] def options = (findProperty("android.packagingOptions.$prop") ?: "").split(","); // Trim all elements in place. for (i in 0.. 0) {
println "android.packagingOptions.$prop += $options ($options.length)"
// Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
options.each {
android.packagingOptions[prop] += it
}
}
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
if (isGifEnabled) {
// For animated gif support
implementation("com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}")
}
if (isWebpEnabled) {
// For webp support
implementation("com.facebook.fresco:webpsupport:${reactAndroidLibs.versions.fresco.get()}")
if (isWebpAnimatedEnabled) {
// Animated webp support
implementation("com.facebook.fresco:animated-webp:${reactAndroidLibs.versions.fresco.get()}")
}
}
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
}
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'
```
#### `MainApplication.kt`:
```kotlin
package com.audrey.audrey.dev
import android.app.Application
import android.content.res.Configuration
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ReactNativeHostWrapper
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
this,
object : DefaultReactNativeHost(this) {
override fun getPackages(): List {
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return PackageList(this).packages
}
override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
)
override val reactHost: ReactHost
get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
SoLoader.init(this, false)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
ApplicationLifecycleDispatcher.onApplicationCreate(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
}
}
```
#### `AndroidManifest.xml`:
```xml
```
Environment
Click To Expand
**`react-native info` output:** ``` System: OS: macOS 14.5 CPU: (14) arm64 Apple M3 Max Memory: 587.88 MB / 36.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 18.17.1 path: /private/var/folders/nm/fpbywkw56d74gt4309qd68bm0000gn/T/xfs-542320a6/node Yarn: version: 3.2.0 path: /private/var/folders/nm/fpbywkw56d74gt4309qd68bm0000gn/T/xfs-542320a6/yarn npm: version: 9.6.7 path: /usr/local/bin/npm Watchman: Not Found Managers: CocoaPods: version: 1.15.2 path: /opt/homebrew/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 23.2 - iOS 17.2 - macOS 14.2 - tvOS 17.2 - visionOS 1.0 - watchOS 10.2 Android SDK: Not Found IDEs: Android Studio: 2023.1 AI-231.9392.1.2311.11255304 Xcode: version: 15.2/15C500b path: /usr/bin/xcodebuild Languages: Java: version: 17.0.10 path: /usr/bin/javac Ruby: version: 3.3.0 path: /opt/homebrew/opt/ruby/bin/ruby npmPackages: "@react-native-community/cli": Not Found react: Not Found react-native: installed: 0.74.2 wanted: 0.74.2 react-native-macos: Not Found npmGlobalPackages: "*react-native*": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: Not found newArchEnabled: Not found ``` - **Platform that you're experiencing the issue on**: - [] iOS - [x] Android - [ ] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `19.2.2` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y` & `5.3.3`
React Native Firebase
andInvertase
on Twitter for updates on the library.