Somewhat randomly my login flow stops working for some users when using google as a login provider (possibly facebook too, unsure) on iOS. They are able to log in on desktop using google login with the same app bundle. I think this is happening for ~1/10 users.
After a user selects which google account to use, the google redirects back to my app. The onAuthStateChange
triggers, but the user is null. This is after successfully "logging in" with google. I think this may have to do with users trying to use multiple auth providers and getting stuck in a weird state. I'm not receiving any error or console logs when this happens, it's as if it's a fresh page load instead of a redirect.
I haven't been able to reproduce the issue using my own account until recently. I tried reverting back to earlier builds when the issue wasn't present for my account, with no luck. I'm now unable to log into my own app 😂
in UserProvider.tsx
:
firebaseConfig.apiKey = process.env.REACT_APP_AUTH_API_KEY;
firebaseConfig.authDomain = process.env.REACT_APP_AUTH_DOMAIN;
firebaseConfig.projectId = "redacted";
firebaseConfig.storageBucket = "redacted.appspot.com";
firebaseConfig.messagingSenderId = "redacted";
firebaseConfig.appId = "redacted";
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Firebase Authentication and get a reference to the service
const auth = initializeAuth(app, {
popupRedirectResolver: browserPopupRedirectResolver,
persistence: [indexedDBLocalPersistence, browserLocalPersistence, inMemoryPersistence],
errorMap: debugErrorMap
});
const UserContextProvider = (props) => {
const signInWithGoogle = () => {
signInWithRedirect(auth, googleAuthProvider);
}
const handleUserCredential = async (result: UserCredential) => {
if (result.user) {
const additionalInfo = getAdditionalUserInfo(result)
dispatch({
type: 'SET_ADDITIONAL_USER_INFO', data: {
additionalInfo: additionalInfo,
}
});
}
}
useEffect(() => {
dispatch({ type: 'LOGIN_INITIATED' });
const handleRedirectResult = async () => {
alert("handling redirect result");
const result = await getRedirectResult(auth);
alert(`redirect result: ${result}`);
if (result) {
handleUserCredential(result)
}
}
onAuthStateChanged(auth, async (user: User | null) => {
alert(`on auth change fired: ${user}`);
if (user) {
// set the token now
const token = await getIdToken(user);
const refreshToken = async () => {
return await getIdToken(user, true);
}
onLoginSuccess(user, token, refreshToken);
} else {
onLogoutSuccess();
}
}, (error) => {
onError(error)
});
handleRedirectResult();
}, [])
onLogoutSuccess()
is triggering because user
is null.
PS: I spammed a bunch of alerts in there because I'm struggling to debug on my device, those aren't in my production build.
Just received an email from Google Cloud about this issue. The reason this failure is happening is because my auth domain did not match my custom domain. Many new clients are not allowing 3rd party cookies, which breaks this flow. The fix is to set up your auth domain to match your custom domain.
I had two steps to do this (you may have more if you have not set up your custom domain yet)
authDomain
value to your custom domain.https://yourcustomdomain/__/auth/handler
. Note: this is different than the authorized domains in the identity providers console!