Facebook login with Firebase in React Native error 400 - firebase

I am having trouble to register a user in Firebase with his Facebook credentials in RN. The Facebook and the Firebase apps are setup correctly, since everything is working as expected in Swift. The OAuth redirect URI is also setup correctly.
However when I try to do the same process from RN it fails. My setup is the following, when the user taps my login button I call FB's LoginManager.logInWithReadPermissions(['public_profile', 'email']) and on its success I call FirebaseManager's (which is my custom class for managing Firebase) signUpWithFacebook(). I get a FB access token correctly and I can see that a credential object is created.
However, Firebase always returns the error:
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"A system error has occurred"}],"code":400,"message":"A system error has occurred"}}
The FirebaseManager looks like this:
import { AsyncStorage, NativeModules } from "react-native";
import * as firebase from 'firebase';
const firebaseConfig = {
apiKey: "key",
authDomain: "domain",
databaseURL: "db_url",
projectId: "project_id",
storageBucket: "storage_bucket"
};
const firebaseApp = firebase.initializeApp(firebaseConfig);
const FBSDK = require('react-native-fbsdk');
const {
AccessToken
} = FBSDK;
export default class FirebaseManager {
constructor() {
// Some logic...
}
signUpWithFacebook() {
AccessToken.getCurrentAccessToken().then((data) => {
let accessToken = data.accessToken
console.log('FB accessToken: ' + accessToken)
const provider = new firebase.auth.FacebookAuthProvider();
const credential = provider.credential(accessToken);
console.log('FB credential: ' + credential)
firebase.auth().signInWithCredential(credential)
.then()
.catch((error) => {
console.log('Failed to sign in Firebase with Facebook. ' + error)
})
})
}
}
I would also like to note that Firebase's anonymous & email/password authentication are working with no problem.
My workaround for the moment is to do the Facebook login from Swift and return the user object in RN with a bridge and RN's NativeModules.
Some more info about my project:
react-native: 0.44.2
firebase: 4.0.0
react-native-fbsdk: 0.6.0
Any help would be appreciated!

Might be a long shoot but this looks VERY similar to a an issue in firebase JS SDK. The solution was to not make an instance of FacebookAuthProvider, by changing these lines:
const provider = new firebase.auth.FacebookAuthProvider();
const credential = provider.credential(accessToken);
to this:
var credential = firebase.auth.FacebookAuthProvider.credential(accessToken);

Related

How to create a session cookie for persistent login in Firebase?

I've been going over Manage Session Cookies to get a better understanding of how firebase auth works. However I have run into some trouble when it comes to implementing cookies. I have been able to successfully follow the example up to the section labeled sign-in but have been unable to follow the next step where I generate my session cookie.
I would like to use my cookie as a jwt in order to do checks on users making request to my endpoints and trying to access my site. However I am unable to actually generate a cookie and am unsure why. The syntax is a bit confusing for me because I am using express while they are not.
So to clarify I believe that I have correctly set up my code but due to the fact that I have not been able to create a token I must not have. Also note that I am not doing the csrf step and will come back for that later and am mainly concerned with generating my token. If anyone can point out why my token might not be generating or point me in the right direction I would be grateful.
Code:
import functions from 'firebase-functions'
import { initializeApp } from 'firebase/app';
import { getAuth, getIdToken, signInWithEmailAndPassword } from "firebase/auth";
import express from 'express';
import cors from 'cors';
import pool from './db.js';
import cookies from "cookie-parser";
const firebaseConfig = {
apiKey: process.env.FB_APIKEY,
authDomain: process.env.FB_AUTHDOMAIN,
projectId: process.env.FB_PROJECTID,
storageBucket: process.env.FB_STORAGEBUCKET,
messagingSenderId: process.env.FB_MESSAGINGSENDERID,
appId: process.env.FB_APPID,
measurementId: process.env.FB_MEASUREMENTID,
};
const app = express();
const firebaseApp = initializeApp(firebaseConfig)
const auth = getAuth()
app.use(cors({origin:true}));
app.use(express.json());
app.use(cookies());
app.get('/firebaseLogin/:body',async(req,res)=>{
let {body} = req.params
body = JSON.parse(body)
const expiresIn = 60 * 60 * 24 * 5 * 1000;
try{
let signInAttempt = await signInWithEmailAndPassword(auth,body.user,body.pass)
let idToken = await getIdToken(signInAttempt.user) // Grabs user token after sign in is approved
getAuth()
.createSessionCookie(idToken, { expiresIn })
.then(
(sessionCookie) => {
// Set cookie policy for session cookie.
const options = { maxAge: expiresIn, httpOnly: true, secure: true };
res.cookie('session', sessionCookie, options);
res.end(JSON.stringify({ status: 'success' }));
},
(error) => {
res.status(401).send('UNAUTHORIZED REQUEST!');
}
);
}catch(error){
res.json(error)
}
})

Error when attempting to call SignInWithRedirect for Google sign-in. React Native, Expo, Firebase

I have reinstalled firebase, expo, and refactored to be using V9 with no real progress. My signInWithEmailAndPassword works fine but I receive the same error with both popUp and Redirect.
TypeError: (0, \_auth.signInWithRedirect) is not a function. (In '(0, \_auth.signInWithRedirect)(auth, provider)', '(0, \_auth.signInWithRedirect)' is undefined)
I believe that it must not be importing correctly but I do not see how. I have authorized google auth in the firebase console and as stated tested the standard sign in and create user functions and they both have no error. My config and initialization both work for standard auth as well as firestore connections.
Import statements :
import {
getAuth,
onAuthStateChanged,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
signInWithRedirect,
GoogleAuthProvider,
} from "firebase/auth";
Handle Google sign in function :
const auth = getAuth();
const signInWithGoogle = () => {
const provider = new GoogleAuthProvider();
signInWithRedirect(auth, provider)
.then((*result*) => {
*// This gives you a Google Access Token. You can use it to access the Google API.*
const credential = GoogleAuthProvider.credentialFromResult(*result*);
const token = credential.accessToken;
*// The signed-in user info.*
const user = *result*.user;
*// ...*
})
.catch((*error*) => {
*// Handle Errors here.*
const errorCode = *error*.code;
const errorMessage = *error*.message;
*// The email of the user's account used.*
const email = *error*.email;
*// The AuthCredential type that was used.*
const credential = GoogleAuthProvider.credentialFromError(*error*);
*// ...*
});
};
Any guidance on what I am missing is greatly appreciated.

firebase signInWithRedirect with microsoft oauth provider encounters 400 and immediately redirects to original page

I have have an GCP Identity Platform + Firebase app using a Microsoft Active Directory Oauth Provider.
When calling signInWithRedirect it gets a 400 with the url
https://www.googleapis.com/identitytoolkit/v3/relyingparty/createAuthUri?key=<api-key>
(note, I am redacting my specific values)
The payload it sends looks like
{
"providerId": "microsoft.com",
"continueUri": "https://<my-gcp-project-id>.firebaseapp.com/__/auth/handler",
"customParameter": { "tenant": "<my-domain>", "redirect_uri": "http://localhost:3000/callback" }
}
Config
const config = {
apiKey: "<api-key>",
authDomain: "<my-domain>",
};
const firebaseApp = firebase.initializeApp(config);
const firebaseAuthApp = firebaseAuth.getAuth(firebaseApp)
const provider = new firebaseAuth.OAuthProvider('microsoft.com');
provider.setCustomParameters({
tenant: 'mydomain.com',
redirect_uri: 'http://localhost:3000/callback',
});
Triggering auth:
const handleClick = () => {
firebaseAuth.signInWithRedirect(firebaseAuthApp, provider)
}
The issue was an incorrect redirect URI defined in the Azure console Active Directory application configuration.
To get my app working (locally) I provided the firebase auth handler callback:
Reference:
https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/error-code-aadsts50011-reply-url-mismatch

firebaseConfig.default.auth promise rejection error

I am trying to signup user with facebook but i am seeing very rigid error and it seems there is no solved help out there so i am asking again
thats my code
async function signInWithFacebook() {
// const appId = Expo.Constants.manifest.extra.facebook.appId;
Facebook.initializeAsync(appid)
const permissions = ['public_profile']; // Permissions required, consult Facebook docs
const {
type,
token,
} = await Facebook.logInWithReadPermissionsAsync(
{permissions}
);
if(type == "success"){
const credential = initFirebase.auth.FacebookAuthProvider.credential(token);
initFirebase.auth().signInWithCredential(credential)
.catch(err => {
console.log(err)
})
}
}
i am using appid in strings but i have not added it here hope you understand that.
and the error is this
this is my firebase config file code
import firebase from "firebase/app"
import "firebase/firestore"
import "firebase/auth"
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "xxxxxxxx",
authDomain: "xxxxxx",
databaseURL: "xxxxxx",
projectId: "xxxx",
storageBucket: "xxxxx",
messagingSenderId: "xxxxx",
appId: "xxxxx"
};
// Initialize Firebase
const initFirebase = firebase.initializeApp(firebaseConfig);
export default initFirebase
variable values are hidden because of privacy .i worked with firestore and that worked but i am seeing issue with auth with facebook .
i am using react native , firebase , expo and not firebase sdk
You don't have to register a Facebook App for Login with Facebook using Firebase. You can use the below code with Firebase Facebook Authentication enabled in the console.
export const loginWithFacebook = (accessToken) => {
const credential = initFirebase.auth.FacebookAuthProvider.credential(accessToken);
return new Promise((resolve, _reject) => {
signInWithCredential(credential).then(response => {
resolve(response);
});
});
};

Firebase function triggering on auth displayName update? [duplicate]

I need to run a Firebase function whenever my user updates their email address, except auth only has onCreate and onDelete. How can I react to email updates?
It's not possible today to directly react to an email address changing in Firebase Authentication. If you'd like to see that as a feature, please file a feature request.
You can react to it indirectly by having your app listen to authentication events (Android), take the User object delivered to your listener, and write the user's email address to a RealtimeDatabase location (or Firestore document) for that user's UID. Then, you can have a database trigger that tracks the location of your users in the database, and react to the change there.
My Workaround Use functions.https.onCall to create an HTTPS callable function.
Firebase Function
exports.onUpdateUserEmail = functions.https.onCall((data, context) => {
const uid = context.auth.uid;
const email = context.auth.token.email || null;
return admin.
firestore()
.collection("users")
.doc(uid)
.set({email});
});
Deploy
$ firebase deploy --only functions:addMessage
Call your Fonction in your app nodejs example firebase v9
import { initializeApp } from 'firebase/app';
import { getAuth, updateEmail } from "firebase/auth";
import { getFunctions, httpsCallable } from 'firebase/functions';
const app = initializeApp({
projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
});
const functions = getFunctions(app);
const onUpdateEmail = httpsCallable(functions, 'onUpdateUserEmail');
const auth = getAuth();
updateEmail(auth.currentUser, "user#example.com").then(() => {
// Email updated!
onUpdateEmail();
}).catch((error) => {
// An error occurred
// ...
});

Resources