I'm using Google firebase v9. On the first sign in, usually there would be a pop up for user to choose which email to sigh in with, but for some reason, when I sign in, it automatically send me to the chat page automatically. I tried delete user in my firebase app and tried again and get the same result. What am I doing wrong?
firebase.js:
import { GoogleAuthProvider } from 'firebase/auth';
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {//myap config};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const provider = new GoogleAuthProvider();
export { auth, provider };
login-page:
import { auth, provider } from '../firebase';
import { useAuthState } from 'react-firebase-hooks/auth';
import { useNavigate } from 'react-router-dom';
import { signInWithPopup } from 'firebase/auth';
function Header(){
const [user] = useAuthState(auth);
const navigate = useNavigate();
const signIn = (e) => {
signInWithPopup(auth, provider)
.then(() => navigate('/channel'))
.catch((error) => alert(error.message));
};
return (
<buttononClick={!user ? signIn : () => navigate('/channel')}>Login</button/>
);
};
Maybe It's because I am already sign-in on chrome? If someone can check my code and verified, that would be awesome.
It sounds like your app is already associated with your Google account. Signing out does not sever that association.
Removing that association is described in the Remove third-party account access, but mostly consists of going to the list of Third-party apps with account access and removing your app from that list.
If that doesn't do it, have a look at the results on forcing the account picker to show up.
Related
I can't firebase v9 enableIndexedDbPersistence in a nextjs pwa.
this erros are trow
index.js // firebase main
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { getFirestore } from 'firebase/firestore'
import { getStorage } from 'firebase/storage'
const firebaseConfig =
process.env.NEXT_PUBLIC_FIREBASE_CONFIG
const app = initializeApp(JSON.parse(firebaseConfig))
export const db = getFirestore(app)
// enableIndexedDbPersistence(db) // >>> if put here it said can't be invoked after getFirestore or any other funtion
export const auth = getAuth(app)
export const storage = getStorage(app)
So where should i invoke
The enableIndexedDbPersistence(db) function must be called before . From its documentation:
Must be called before any other functions (other than
{#link initializeFirestore}, {#link (getFirestore:1)} or
{#link clearIndexedDbPersistence}.
So getFirestore(app) is actually exempted from that, in contrast what you stated in the comment of your code snipped:
// >>> if put here it said can't be invoked after getFirestore or any other function
Consequently, my guess would be that you might use the exported db before the promise of enableIndexedDbPersistence(db) completes.
You could resolve this in different ways, such as wrapping it in a service or method and make sure you are await-ing the promise, or generally change your app that db is not used right away.
In my Ionic PWA app, I'm successfully using the following:
import { getFirestore, enableIndexedDbPersistence } from "firebase/firestore";
import { initializeApp } from "firebase/app";
const firebaseConfig = {
// ...
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
enableIndexedDbPersistence(db)
.then(() => console.log("Enabled offline persistence"))
.catch((error) => {
if (error.code == "failed-precondition") {
// Multiple tabs open, persistence can only be enabled
// in one tab at a a time.
// ...
} else if (error.code == "unimplemented") {
// The current browser does not support all of the
// features required to enable persistence
// ...
}
});
This is very similar to your snipped indeed. But the first access to Firestore happens after via user interaction, and not right away.
I have a React Native app that needs to be served on its web version. So, I need to implement the Google OAuth with the firebase js lib.
I'm following these steps.
If I use the same code from the docs I have a weird error (of course I put the proper config object in the initializeApp method):
import * as React from 'react';
import * as WebBrowser from 'expo-web-browser';
import { ResponseType } from 'expo-auth-session';
import * as Google from 'expo-auth-session/providers/google';
import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider, signInWithCredential } from 'firebase/auth';
import { Button } from 'react-native';
// Initialize Firebase
initializeApp({
/* Config */
});
WebBrowser.maybeCompleteAuthSession();
export default function App() {
const [request, response, promptAsync] = Google.useIdTokenAuthRequest(
{
clientId: 'Your-Web-Client-ID.apps.googleusercontent.com',
},
);
React.useEffect(() => {
if (response?.type === 'success') {
const { id_token } = response.params;
const auth = getAuth();
const credential = GoogleAuthProvider.credential(id_token);
signInWithCredential(auth, credential);
}
}, [response]);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
}
The error is:
I get this error specifically when I call signInWithCredential()
The strange thing is that in the Network tab (Chrome DevTools) I have a successful response:
And the problem is: If I want to get the user information with onAuthStateChanged, it is null because the login attempt just failed (despite the dev-tools being all good)
Note: I've tried with a new starter project, moving our dependencies with the same version as they are here and it's working.
But I can't figure out what can be happening with this project.
EDIT: Adding images of the requests that are being made:
The firebase docs show them using the app instance inside the getAuth() call, in one portion of the docs
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
// ...
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app); //I'm talking about this line
Then in the very next section on the same page, they go ahead and use getAuth() without the app instance, in order to sign in a user with email.
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
const auth = getAuth();
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
const user = userCredential.user;
})
.catch((error) => {
console.log(error)
});
What is the correct way to use it?
The getAuth() function without parameters will use the default initialized instance of Firebase. If you have multiple instances of Firebase i.e. multiple projects, then you must pass the app instance to specify which project's auth that auth instance must use.
const app1 = initializeApp(project1Config);
const app2 = initializeApp(project2Config, "app2");
const auth1 = getAuth(); // or getAuth(app1), uses app1 as it's default,
const auth2 = getAuth(app2); // uses app2
I am using firebase web sdk without React. I have 4 pages in my application. I am using express js in for each pages to send html file of that route.
I have a file called common.js in which I defined methods that will be shared by all pages. In the same file I defined a method to act on auth changed is as following:
Modified below code
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { firebaseConfig } from './firebase.config';
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
const auth = getAuth(firebaseApp);
const addNavbar = () => {
$('#nav').load('nav.html', () => {
document.getElementById('btnSignOut').addEventListener('click', (e) => {
auth.signOut();
});
});
}
// createAlert, createEditDeleteButtons, displayLoaderAndHideApp defined here
const unsubscribeOnAuthStateChanged = onAuthStateChanged(auth, async (user) => {
if (user) {
window.location.replace('/home');
} else {
window.location.replace('/login');
}
});
export {
addNavbar, auth, createAlert, createEditDeleteButtons, db, displayLoaderAndHideApp,
};
On each page I first call handleOnAuthStateChanged(), and it is also called after successful login. I want to persist the auth so I came across setPersistence(), so I used it in login.js and is as follows:
import { browserLocalPersistence, browserSessionPersistence, setPersistence, signInWithEmailAndPassword } from 'firebase/auth';
import { auth, handleOnAuthStateChanged } from './common';
document.getElementById('btnSignin').addEventListener('click', async (e) => {
e.preventDefault();
try {
const form = document.querySelector('form.formLogin');
const email = form.email.value.trim();
const password = form.password.value;
await setPersistence(auth, browserLocalPersistence);
await signInWithEmailAndPassword(auth, email, password);
handleOnAuthStateChanged(auth.currentUser); // here auth will retrieve the new logged in user
} catch (e) {
console.error(e);
}
});
If I use onAuthStateChanged() on other pages my user is null then I am stuck in a loop.
Am I missing something?
Update
All of the minimal code is after removing all the functionalities except a few that might causing the problem.
I have a file called nav.html that is loaded into page by common.js and is as defined above.
Code for home, page 1 and page 2 adds navigation by calling addNav. Home will import methods from common.js, page 2's js, and page 1's js. Home page's js is as following:
import { addDoc, collection, deleteDoc, doc, getDocs, onSnapshot, query, setDoc, where } from 'firebase/firestore';
import { addNavbar, createAlert, createEditDeleteButtons, db, displayLoaderAndHideApp as displayLoader } from './common';
// imports from page 1 and page 2
addNavbar();
// Other methods are defined here...
// Nothing is exported as of now..
Firebase automatically persists the auth state on most browser environments, and restores it on app/page reload. To detect this restore of auth state (and other auth state changes) you will need to register an auth state listener with the SDK as shown in the first code fragment in the documentation on getting the current user:
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
Most of the code of your handleOnAuthStateChanged can probably go into this handler.
As per documentation of firebase for using re-CAPTCHA.
I created a div inside sign-up form.
<div id="recaptcha-container"></div>
and used the code as given in documentation -
import { getAuth, RecaptchaVerifier } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-auth.js";
const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {}, auth);
But when I reload my sign-up.php page, my captcha didn't show. Even I didn't get any error in console.
Why am I not able to see captcha layout ?
I think you should specify the size to normal, try this:
import { getAuth, RecaptchaVerifier } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-auth.js";
const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {'size': 'normal'}, auth);
pass the firebase config instance in getAuth
const app = initializeApp(firebaseConfig);
import { getAuth, RecaptchaVerifier } from "https://www.gstatic.com/firebasejs/9.1.1/firebase-auth.js";
const auth = getAuth(app);
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', { 'size': 'normal' }, auth);
recaptchaVerifier.render();
for me also same problem after pass this firbaseConfig instanse it shows the reCAPTCHA widget and render it