Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛] 🔥 Issue with Firebase refresh token + get currentUser functions #8053

Open
2 of 10 tasks
guillaume-lyynk opened this issue Oct 9, 2024 · 2 comments
Open
2 of 10 tasks

Comments

@guillaume-lyynk
Copy link

Issue

Hi reader 👋

I use React native, Expo and some react-native-firebase library (more info bellow).

I'm facing a Firebase error (it seems) with token refresh and get currentUser.

Problem 1

For example, a user connects to my app, closes it after 5 minutes and reopens it the next day (the token has therefore expired, as its validity period is 1 hour).
In the back-end logs, I can see that some calls are made with a token that has been expired for several hours.

Given my code (that the token is checked before each call), I don't see how my api can receive calls with an expired token.

I also found that several other people potentially had similar concerns:

And apparently, the problem is only on iOS.

So I'm think that Firebase's token refresh function may have some problems.

Problem 2

Also, sometimes the currentUser is not retrieved with the function firebase.auth().currentUser; (returns null) even though I'm in the connected area.
This append on Android and iOS.


In my front, endpoint calls are handled simply:

  • 1- Get accessToken from currentUser
  • 2a- If the token is still valid -> it is returned
  • 2b- If the token is no longer valid -> force its regeneration then return it
  • 3- Call endpoint with the token (still valid or renewed) in Authorization header

(See the logic/code bellow)

Do I missing something or any idea ?

Thanks for reading


Project Files

Javascript

const getAccessToken = async (shouldForce?: boolean) => {
  	const currentUser = firebase.auth().currentUser;

  	if (currentUser) {
    		const idTokenResult = await currentUser.getIdTokenResult();

    		if (shouldForce || isTokenExpired(idTokenResult.expirationTime)) {
			return await currentUser.getIdToken(true);
    		}

    		return idTokenResult.token;
  	}

  	return null;
};


const fetchApi = () => {
	const accessToken = await getAccessToken();

  	let response = await fetch(url, {
		Authorization: `Bearer ${accessToken}`
		// …
  	});

  	if (response.status === 401) {
    		const newToken = await getAccessToken(true);

    		if (newToken) {
      			response = await fetch(url, {
				Authorization: `Bearer ${newToken}`
				// …
  			});
    		}

    		if (response.status === 401) {
      			await signOut();
    		}
  	}

  	const responseData = await getResponseBody(response);

 	 if (!response.ok) {
    		throw new ResponseError(response.status, response, responseData);
  	}

  	return responseData;
};

package.json:

"react-native": "0.74.5",
"expo": "^51.0.31",
"@react-native-firebase/app": "20.1.0",
"@react-native-firebase/app-check": "20.1.0",
"@react-native-firebase/auth": "20.1.0",
"@react-native-firebase/firestore": "20.1.0",
"@react-native-firebase/messaging": "20.1.0",

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.m:

// 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:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

 System:
  OS: macOS 15.0
  CPU: (8) arm64 Apple M3
  Memory: 136.52 MB / 8.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.9.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.8.3
    path: /opt/homebrew/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.18034.62.2412.12266719
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.12
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.5
    wanted: 0.74.5
  react-native-macos: Not Found
  • Platform that you're experiencing the issue on:
    • iOS
    • 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:
    • 20.1.0
  • Firebase module(s) you're using that has the issue:
    • "@react-native-firebase/app": "20.1.0"
    • "@react-native-firebase/app-check": "20.1.0"
    • "@react-native-firebase/auth": "20.1.0"
    • "@react-native-firebase/firestore": "20.1.0"
    • "@react-native-firebase/messaging": "20.1.0"
  • Are you using TypeScript?
    • YES & ~5.5.4


@russellwheatley
Copy link
Member

@guillaume-lyynk - not sure what the token is used for in the backend which might shed light on why it is still valid?

Also

const idTokenResult = await currentUser.getIdTokenResult();

This should also get fresh token if it has expired in any event.

Also - if the firebase admin sdk you're using is allowing use of expired token, it seems it is more likely a bug in that SDK rather than React Native Firebase/firebase-ios-sdk. I'm very skeptical that something as essential as token expiration isn't taken into account in firebase-admin-sdk.

As for your second problem, we would need a minimal reproduction to have a look at this issue 🙏

@youssdevx
Copy link

Well, in some cases (we couldn't identify when it happens exactly)
const idTokenResult = await currentUser.getIdTokenResult();
throws an error : [auth/network-request-failed] A network error has occurred, please try again.
image

We are not the only ones to face this issue : #4934

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants