Facebook Login in React Native with Firebase Authentication
Learn how to fix the "Duplicate credential received" error in Facebook Login with React Native and Firebase Auth. A detailed guide for both Android and iOS, including nonce handling, platform differences, and secure implementation tips.
I recently faced an interesting challenge while integrating Facebook login into a React Native app using Firebase Authentication. At first, I thought it would be straightforward, but as I dug deeper, I encountered an error that took a full day of troubleshooting, research, and testing to solve.
The issue I faced was platform-specific: while the implementation for Android was smooth, iOS required some slight adjustments. Once I figured out the differences, I was ready for testing. And that’s when the real trouble began. The first login attempt worked perfectly. But every subsequent login attempt threw an error:
[Error: [auth/unknown] Duplicate credential received. Please try again with a new credential.
The message was cryptic, and my initial online search led nowhere. I tried various quick fixes, and each failed login just deepened my frustration. However, after hours of experimenting and learning more about the differences between limited login on iOS and the standard login flow, I finally cracked the code. The problem boiled down to a need for a new nonce each time the user attempted to log in. Here’s my solution and the journey that got me here!
Solution: Facebook Login with Firebase Auth
✅ Prerequisites
Ensure you have:
- A Firebase project with Facebook Authentication enabled
- A React Native setup with:
npm install @react-native-firebase/auth npm install react-native-fbsdk-next
🧩 Implementation
const onFacebookButtonPress = async () => {
try {
// Step 1: Generate nonce
const nonce = generateRandomString();
const nonceSha256 = await sha256(nonce);
// Step 2: Facebook login with platform-specific flow
const result = await LoginManager.logInWithPermissions(
["public_profile", "email"],
"limited",
nonceSha256
);
if (result.isCancelled) throw "User cancelled the login process";
// Step 3: Obtain access/auth token
const data = await (Platform.OS === "ios"
? AuthenticationToken.getAuthenticationTokenIOS()
: AccessToken.getCurrentAccessToken());
if (!data) throw "Something went wrong obtaining access token";
// Step 4: Build Firebase credential
let facebookCredential;
if (Platform.OS === "ios") {
facebookCredential = auth.FacebookAuthProvider.credential(
data.authenticationToken,
nonce
);
} else {
facebookCredential = auth.FacebookAuthProvider.credential(data.accessToken);
}
// Step 5: Sign in via Firebase
const userCredential = await auth().signInWithCredential(facebookCredential);
return userCredential;
} catch (error) {
console.log("error", error);
crashlytics().recordError(error);
}
};
🔍 Code Walkthrough
Let’s break down the important sections of the code above.
Please make sure to update tests as appropriate.
Step 1: Generate a Unique Nonce
Each login attempt needs a unique nonce. This step prevents the “Duplicate credential received” error by ensuring that every login is treated as a new, unique attempt.
Step 2: Hash the Nonce with SHA-256
Firebase expects the nonce to be hashed for security.
Step 3: Handle Platform-Specific Tokens
Android and iOS handle access tokens differently. iOS’s limited login feature uses an AuthenticationToken with the nonce, while Android uses a standard AccessToken.
Step 4: Create a Firebase Credential
With the generated nonce and token, we create a Firebase credential using the FacebookAuthProvider. Firebase will then authenticate the user.
Step 5: Sign in and Handle Errors
After signing in, I added error handling to capture and log any issues that arise. This helps with debugging, especially in production, where I use Crashlytics for error reporting.
💡 Lessons Learned
- Nonce is Key: To prevent “duplicate credential” issues, always generate a new nonce with each login attempt.
- Platform Differences: iOS and Android handle access tokens differently, so check the documentation to see if you need to handle each platform separately.
- Error Logging is Essential: Logging errors with tools like Crashlytics can help you track down issues faster, especially when the problem only appears in production.
✅ Conclusion
After a day of debugging and testing, I finally solved the duplicate credential issue with Facebook login in React Native. If you’re facing similar issues, I hope this article helps you save some time and avoids the same frustration! With these steps, you can integrate Facebook login into your app securely and with confidence.
If you enjoyed this article, follow me for more insights on mobile development and Firebase integrations. Happy coding!
Let's bring your app idea to life
I specialize in mobile and backend development.
Share this article
Related Articles
Advanced Form Handling in React Native: Validation, Multi-Step Forms, and State Management
Master form handling in React Native. Learn validation strategies, async field validation, multi-step wizards, error handling, accessibility, and implement production-ready forms with React Hook Form and custom validators.
API Integration Patterns in React Native: RESTful Services, Caching, and Error Handling
Master API integration in React Native. Learn to build robust API services with error handling, retry logic, request caching, pagination, authentication, rate limiting, and type-safe API clients for production apps.
Building Offline-First React Native Apps: Complete Implementation Guide
Master offline-first architecture in React Native. Learn AsyncStorage, Realm, SQLite, sync strategies, and conflict resolution for seamless offline UX.