react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

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

Open guillaume-lyynk opened this issue 1 year ago • 0 comments
trafficstars

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:

  • https://github.com/invertase/react-native-firebase/issues/7900
  • https://github.com/invertase/react-native-firebase/issues/6341

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
  • [x] 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
    • [x] 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

guillaume-lyynk avatar Oct 09 '24 10:10 guillaume-lyynk