invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.69k stars 2.21k forks source link

[🐛] Android 13 SMS Code Has Expired, for every 13 device after release not able to verify #7344

Closed ReactNativeDev2296 closed 9 months ago

ReactNativeDev2296 commented 1 year ago

Hello @mikehardy, @andymatuschak , @gilbertl @dlackty @felixclack I am unable to log into any Android 13 device, please provide a solution

**Library version:

@react-native-firebase/analytics": "18.3.1",
    "@react-native-firebase/app": "18.3.1",
    "@react-native-firebase/auth": "18.3.1",
    "@react-native-firebase/messaging": "18.3.1",
    react-native: "0.61.3"`

**Build.gradle file(Android):

        minSdkVersion = 21
        compileSdkVersion = 33
        targetSdkVersion = 33
        supportLibVersion = "30.0.0"
        multiDexEnabled = true
        androidXCore = "1.7.0"`

***Build.gradle(android/app):

    implementation platform('com.google.firebase:firebase-bom:32.2.0')
    implementation 'com.google.firebase:firebase-auth'`

MicrosoftTeams-image (41)

ReactNativeDev2296 commented 1 year ago

Hi @mikehardy , @andymatuschak , @felixclack , @dlackty , @gilbertl Please help us with the issue

ReactNativeDev2296 commented 1 year ago

Hi @mikehardy , @andymatuschak , @felixclack , @dlackty , @gilbertl

any update for the above bug?

mikehardy commented 1 year ago
implementation platform('com.google.firebase:firebase-bom:32.2.0')

You are overriding the firebase BoM, that's for advanced use cases and you assume the risk of breakage. It may be the cause of this. Have you tried removing it, updating to react-native-firebase current and letting it handle the BoM resolution as it will do for you here:

https://github.com/invertase/react-native-firebase/blob/c9b695aa8fd75d5a1d070ecbb6bb9ac4e9ff062e/packages/app/package.json#L84

Also, I do not believe this is necessary, the auth package will bring it in for you, so this should be removed from your gradle files along with the BoM entry

implementation 'com.google.firebase:firebase-auth'`

It does not appear that there were auth-related issues, however, you never know, and first job of reproduction is to make sure you're not just discovering old bugs, so you want to get on current software

That said, I do not see any issues in the upstream firebase-android-sdk repo about this, and the last time I saw this it was more related to using the wrong SMS code - usually a subtle issue where somehow multiple SMS codes may be requested, then there is a race condition, and the wrong one is used. Perhaps that is it, or similar to it?

No one else is reporting this and Android 13 has been out for a while though, so even though I don't have concrete evidence of it I would strongly suspect this is a project-specific issue

ReactNativeDev2296 commented 1 year ago

Hi @mikehardy , @andymatuschak @felixclack @dlackty I removed what you suggested but some Android 13 is working fine but Samsung a34 OS version 13 still shows invalid OTP and one more think when we are using old mobile number which are already available into fires store is was working fine but newly mobile number is not working it was throwing errors

ReactNativeDev2296 commented 1 year ago

Hello @mikehardy ,

Today we are trying to deliver this project to the client but this issue is happening again can you give us an emergence solution?

ReactNativeDev2296 commented 1 year ago

Hello @mikehardy @andymatuschak @felixclack @dlackty ,

I found the root cause of the issue:- The issue is with Android 13. When we try to set up accounts using a SIM card and create new accounts, the device generates an invalid OTP error. It will function well if we try to use a different cellphone number.


  package="com.SEWAMOApp">

  <!--  Keep only the permissions used in your app  -->

  <uses-feature
      android:name="android.hardware.telephony"
      android:required="true" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      android:largeHeap="true"
        android:usesCleartextTraffic="true">

      <!-- Add license key in meta-data tag here. This should be inside the application tag. -->

      <activity
        android:name=".MainActivity"
        android:exported = "true"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustPan"
        >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
      <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>

    <!-- You will only need to add this meta-data tag, but make sure it's a child of application -->
   <meta-data
     android:name="com.google.android.geo.API_KEY"
     android:value="@string/google_maps_key"/>

   <!-- You will also only need to add this uses-libray tag -->
   <uses-library android:name="org.apache.http.legacy" android:required="false"/>

    </application>
    <queries>
      <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:mimeType="*/*" />
      </intent>
    </queries>

</manifest>
ReactNativeDev2296 commented 1 year ago

Hello @mikehardy , @andymatuschak @felixclack @dlackty , Please read the below logs also from the firebase console side


  "insertId": "-t4elkdc8ig",
  "jsonPayload": {
    "methodName": "google.cloud.identitytoolkit.v1.AuthenticationService.SignInWithPhoneNumber",
    "status": {
      "message": "SESSION_EXPIRED",
      "code": 3
    },
    "requestMetadata": {
      "callerIp": "103.167.52.19",
      "callerSuppliedUserAgent": "Dalvik/2.1.0 (Linux; U; Android 13; M2012K11AI Build/TKQ1.220829.002),gzip(gfe),gzip(gfe)"
    },
    "@type": "type.googleapis.com/google.cloud.identitytoolkit.logging.RequestLog"
  },
  "resource": {
    "type": "identitytoolkit_project",
    "labels": {
      "project_id": "sewamo-ec72e"
    }
  },
  "timestamp": "2023-10-12T04:13:00.101Z",
  "severity": "ERROR",
  "logName": "projects/sewamo-ec72e/logs/identitytoolkit.googleapis.com%2Frequests",
  "receiveTimestamp": "2023-10-12T04:13:00.875676805Z"
}
ReactNativeDev2296 commented 1 year ago

Hello @mikehardy @andymatuschak @felixclack @dlackty ,

Today we are trying to deliver this project to the client but this issue is happening again can you give us an emergency solution?

ReactNativeDev2296 commented 1 year ago

Hello @mikehardy , Please provide me with an update, because firebase-support@google.com said that this is not our side issue it is library side issue

ReactNativeDev2296 commented 1 year ago

Hi @andymatuschak, Please help us with what we can do because all android 13 users are not able to login

ReactNativeDev2296 commented 1 year ago

Hello @mikehardy @felixclack @dlackty @gilbertl ,

At Least provide a solution

ozgencozben commented 1 year ago

Hi, this is very critical issue, we are about to deliver our project to client but we find out that some users cannot join into our application. @mikehardy & @andymatuschak we need your help here. Please give us some help or any other suggestion ! Thanks CC : @KuldipReactNative

mikehardy commented 1 year ago

Hi there, with apologies, that is not how open source works - there is no ability to demand emergency solutions, and open source development is not responsive to commercial deadlines of people using the freely provided software. I refer you to this:

https://github.com/invertase/react-native-firebase/blob/2d8ac144a14e79ce1846ecab077f8d7b69d11f05/LICENSE#L13C1-L15C73

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

It is imperative to understand the implications of that, which is that you are the developer of the software, not the consumer. If there is a problem that is affecting you and there is insufficient responsiveness from others, you must dedicate the resources to fix the problem. I am also just a developer of the software, alongside you. I am willing to help others but I am not obligated in specific cases.

I have mentioned above specifically that I do not reproduce this. I will also note and emphasize very strongly that OTPs in general are lossy. A specific example: SMS messages may fail delivery at the carrier level for a variety of reasons, in my personal experience with an app in Ecuador some numbers that were recently ported between carriers and all numbers on one specific carrier were simply not delivered ever.

For that reason, my strong advice is: You must not rely on OTP as an exclusive means of authentication. You need a backup. At which point this is no longer an emergency for you.

Following that, I suggest you pursue this with a minimal reproducible example in firebase-android-sdk based on their quickstart to show them the problem as they will have to resolve it if you can reproduce it.

mikehardy commented 1 year ago

As a separate moderation note: do not repeatedly tag people in your comments without advancing the topic (through personal effort at demonstrating a reproduction or developing a solution). Some of your comments have been reported (fairly, in my opinion) as spam and I will close those comments as such.

zahid023 commented 1 year ago

i am also having this issue in production application ,users are giving negative reviews for this , pixel and samsang devices are showing error like "auth/session-expired" after inputing OTP , IOS working fine

Dependencies "@react-native-firebase/analytics": "18.3.1", "@react-native-firebase/app": "18.3.1", "@react-native-firebase/app-check": "18.3.1", "@react-native-firebase/auth": "18.3.1", "@react-native-firebase/crashlytics": "18.3.1", "@react-native-firebase/messaging": "18.3.1", "@react-native-firebase/storage": "18.3.1",

@mikehardy is there any way to fix it ?

ReactNativeDev2296 commented 1 year ago

i am also having this issue in production application ,users are giving negative reviews for this , pixel and samsang devices are showing error like "auth/session-expired" after inputing OTP , IOS working fine

Dependencies "@react-native-firebase/analytics": "18.3.1", "@react-native-firebase/app": "18.3.1", "@react-native-firebase/app-check": "18.3.1", "@react-native-firebase/auth": "18.3.1", "@react-native-firebase/crashlytics": "18.3.1", "@react-native-firebase/messaging": "18.3.1", "@react-native-firebase/storage": "18.3.1",

@mikehardy is there any way to fix it?

correct @zahid023 it is negative

mikehardy commented 1 year ago

Those are old versions.

I have been tagged again but there is no extra logging or reproducible example that advances the issue

So the previous 2 comments are the equivalent of an otherwise not useful '+1', except they are worse, they indicate an unwillingness to test the current release and report results on it.

ozgencozben commented 1 year ago

hi @mikehardy as i can see some other projects has same issue, also as you know we already share all techical details by@ReactNativeDev2296. If you handle this issue ( i am sure it ll easy to get action this kind of changes from your team ) we ll glad. Thanks.

mikehardy commented 1 year ago

Have you tried on current versions?

ozgencozben commented 1 year ago

@mikehardy Android 13 works perfectly with Recaptcha, without Recaptcha but not with it (previous version 18.3.1) or the current version.

mikehardy commented 1 year ago

Your statement seems to read like it works great with and without recaptha.

Do you have an app.js I could use to reproduce?

zahid023 commented 1 year ago

firebase sdk tries to auto verify user after msg is received . issue was -> when user receive otp sms -> before user try to fill up otp , in background firebase sdk verified the user -> so when the user tries to login with that otp -> firebase gives this error because , firebase already verified the user in background .

is there any way to disable auto verify ??

ReactNativeDev2296 commented 1 year ago

Your statement seems to read like it works great with and without recaptha.

Do you have an app.js I could use to reproduce?

Hi @mikehardy ,

Please check the below code for more information

componentDidMount() {
    this.subscriber = auth().onAuthStateChanged(this.onAuthStateChanged);
  }

  componentWillUnmount() {
    if (this.subscriber) {
      this.subscriber(); // Unsubscribe on unmount
    }
  }

  onAuthStateChanged = (user) => {
    if (user) {

    }
  }
  async callFirbaseAuth(phone: any) {

   await auth().signInWithPhoneNumber(phone)
      .then(async res => {

        Toast.showWithGravity("OTP sent successfully", Toast.SHORT, Toast.BOTTOM)

        this.setState({ isLoading: false, phoneValue: phone })
        this.props.navigation.replace("Verification", { number: this.state.phoneValue, authConfirmation: res, verificationauthres: res, data: 'LOGIN' })

      }).catch(error => {
        this.setState({ isLoading: false })
        let temp = error.toString()
        if (temp.includes("auth/too-many-requests")) {
          alert("Something: " + temp);
          Toast.showWithGravity("Something went wrong", Toast.LONG, Toast.BOTTOM)
          this.setState({ isLoading: false })
        }
      })
  }
async verififyOTP(){
  try {
        await this.state.verificationauthres.confirm(this.state.OTP).then(async (val: any) => {

          this.setState({ OtpLoader: false, isLoading: false, })

        }).catch((error: any) => {
          console.log("LOG  verifyFirebase", error.toString());
          Toast.showWithGravity("Invalid verification code" + '', Toast.LONG, Toast.BOTTOM)
          this.setState({ isLoading: false, OTP: "" })          
        })
      } catch (error) {

        this.setState({ isLoading: false })
      }
}

index.js


import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';

import { App } from './App';

const snapshots = false;
if (snapshots) {
  require('./indexSnapshot');
}
else {
  AppRegistry.registerComponent(appName, () => App);
  }
ozgencozben commented 1 year ago

hi @mikehardy again please check this post ↑↑↑ : https://github.com/invertase/react-native-firebase/issues/7344#issuecomment-1782789614

ozgencozben commented 12 months ago

@mikehardy any news here ?

mikehardy commented 12 months ago

My work app was quite out of date, so this took a while

With up to date react-native and react-native-firebase on an Android 13 phone, I was able to successfully use phone auth with an sms code sent by firebase

So, I still don't reproduce this and I strongly suspect there is some app-specific implementation detail causing this to happen for you

mikehardy commented 12 months ago

Your "example" is not a reproducible example by the way - it is not minimal, and it is not complete - it includes references to Toast, navigation, state, some indexSnapshot thing, all sorts of things that make it so it does not actually run and may not be used as proof of anything

Creating an example is a vital skill when requesting help. Here's the philosophy, please understand it: https://stackoverflow.com/help/minimal-reproducible-example

For your example I would expect an index.js that does nothing but load App.js, and an App.js that does nothing but

Don't worry about loading state or whatever, just use a simple alert to display results of function calls, you are having an emergency problem right? Simplify things down to their minimum.

ajaymangal7 commented 11 months ago

Got Any Solution for this ?

mikehardy commented 11 months ago

@ajaymangal7 have you read the comment immediately above yours? We need more information from an affected person. Your comment does not supply more information, so no progress towards a solution yet.

gprathour commented 11 months ago

Hey Guys, I believe I was able to find out the root cause of this issue. TBH I'll have to say it is not a bug, it is a feature 😅. @mikehardy please confirm on this.

If we go through the Firebase's official documentation for Phone Auth on Android then they have mentioned,

Auto-retrieval: on some devices, Google Play services can automatically detect the incoming verification SMS and perform verification without user action. (This capability might be unavailable with some carriers.) This uses the SMS Retriever API, which includes an 11 character hash at the end of the SMS message.

Here is the link to this,

https://firebase.google.com/docs/auth/android/phone-auth#onverificationcompletedphoneauthcredential

And it seems like RNFirebase uses this SMS Retriever API too,

https://github.com/invertase/react-native-firebase/issues/3808

So what really happens here is that on some latest Android devices when the SMS is received, the above mentioned SMS Retriever API automatically reads the code and uses it to authenticate / login the user to the app. This all happens in the background and if we have not handled the scenario, the app won't get to know about it. Now when user manually enters the code, and as that code was already consumed in the background, it now says that Code has Expired.

You can confirm this from the Firebase's Authentication console as it will show the timestamp for the user Signed In, even if it said that code expired.

The simple solution to handle this is put onAuthStateChanged listener in your Enter OTP Screen,

useEffect(() => {
    const unsubscribe = auth().onAuthStateChanged((user) => {
        if (user) {
            // Auto Verified
        }
    });
    return unsubscribe;
}, []);

It will get called when the user is authenticated automatically and you can continue from there as per your app's flow.

mikehardy commented 11 months ago

Yes, I believe we document the onAuthStateChanged API for exactly that reason 🤔

Examine the comment in the sample code on same: https://rnfirebase.io/auth/phone-auth#sign-in

github-actions[bot] commented 10 months ago

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.