I want to create a cli in order to create commands to control a website's carousel. But to do that i want to use firebase for login but i don't want to make the user login everytime they run a cli command like start i want to run a command like login and to login them in firebase so when firebase is initialized the next time they don't need to sign in again. In web apps or phone apps it works because the account is remebembered but in a node js server even if i login, the account is never remebered, so firebase.onAuthStateChanged always returns null.
This is what happens on start:
app.listen(5100, () => {
console.log("The slid server has already starterd");
firebase.auth().onAuthStateChanged(user => {
console.log(user);
})
opn("http://localhost:5100");
and the user is always null. So how can i remember the user with firebase in a node js cli?
Please try this, it's from Firebase Official Auth Doc
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
}
});
In your scenario:
app.listen(5100, () => {
console.log("The slid server has already starterd");
firebase.auth().onAuthStateChanged(user => {
if(user){
console.log(user);
}
});
});
opn("http://localhost:5100");
Related
I'm trying to create a web application, where you can log-in and register an account with a google account. I have managed to make it so they can log-in with the signInWithPopup(provider), but not sure how to Implement the sign-up. Any suggestions? or know of any functions in firebase i can use?
There aren't any separate methods to login and sign up when using Google Sign-In or any other provider. If a user with that credential exists then user will be logged in else a new user account will be created. You can then use additionalUserInfo.isNewUser property from the result received from signInWithPopUp method to check if the user is new.
firebase.auth().signInWithPopup(provider).then(function (result) {
const {additionalUserInfo: {isNewUser}} = result;
console.log(isNewUser ? "This user just registered" : "Existing User")
})
For the new Modular SDK (V9.0.0+), the same can be written as:
import { signInWithPopup, getAdditionalUserInfo } from "firebase/auth"
const result = await signInWithPopup(auth, googleProvider);
// Pass the UserCredential
const { isNewUser } = getAdditionalUserInfo(result)
So far, as I understood, you have two options to log in to your website: one is to make a local username/password account on your website, and the other option is to use your google account. I suppose the best way would be to check if the Google account is linked to any existing user using additionalUserInfo.isNewUser, and then linking up your google account with the account that is created via your website locally by following this article: https://firebase.google.com/docs/auth/web/account-linking?hl=lt
Once you have Firebase dependency inside your application. You can use createUserWithEmailAndPassword method to do that.
firebase
.auth()
.createUserWithEmailAndPassword("email#domain.com", "123123")
.then(data => {
data.user.updateProfile({
displayName: this.form.name
}).then(() => {});
})
.catch(err => {
this.error = err.message;
});
Using Firebase Web SDK, I'm requiring users to verify their email before accessing Firestore documents. I have a Firestore rule that gates the document like this:
allow read: if request.auth != null && request.auth.token.email_verified;
I'd like the email verification to be reflected as soon as the user verifies his/her email without requiring the user to sign out and sign back in. Unfortunately onAuthStateChanged() doesn't fire when emailVerified changes, so I'm refreshing the client token by polling for changes to emailVerified. Something like this:
Note: My examples use the new beta Firebase Web SDK V9 (Modular Web SDK) in case the syntax is unfamiliar.
window.setInterval(() => {
reload(auth.currentUser).then(() => {
if (!auth.currentUser?.emailVerified)
return;
// unsubscribe the previous onAuthStateChanged() listener
unsubscribe();
// resubscribe to auth changes
unsubscribe = auth.onAuthStateChanged(user => {
// Yay! user.emailVerified is now true
console.log(user.emailVerified);
});
});
}, 2000);
With the code above, I can get emailVerified to be reflected property inside my web app, but the problem arises when I try to make a request to Firestore:
const unsubscribe = onSnapshot(
doc(db, 'widgets', 'widget1'),
snap => {
console.log(snap);
},
);
That request results in a Firestore permission error. Once the user signs out and signs back in, the Firestore request is accepted.
How can I get the auth token that gets sent to Firestore to be updated with the latest email_verified without the user to sign out and and sign back in?
It turns out that a series of steps need to happen to refresh the token. After email verification, you need to reload the user AND explicitly get a new id token with getIdToken(user, true) after you reload the user. Only after those 2 steps will an updated token be sent to Firestore for queries. You also need to unsubscribe and re-subscribe to onAuthStateChanged manually, as that doesn't get triggered on token change. The modified version of my example is:
window.setInterval(() => {
reload(auth.currentUser).then(() => {
if (!auth.currentUser?.emailVerified)
return;
getIdToken(auth.currentUser, true).then(() => {
// now the new token will be sent to Firestore, yay!
// unsubscribe the previous onAuthStateChanged() listener
unsubscribe();
// resubscribe to auth changes
unsubscribe = auth.onAuthStateChanged(user => {
// Yay! user.emailVerified is now true
console.log(user.emailVerified);
});
})
});
}, 2000);
Please post your answer if there's an easier way. I especially don't like the polling part.
I have a problem with keycloak.js in my Vue3 application
const keycloak = Keycloak(keycloakOptions)
keycloak.init({
onLoad: 'login-required',
checkLoginIframe: false
}).then(async (auth) => {
if (!auth) {
window.location.reload()
} else {
const app = createApp(App)
app.provide(process.env.VUE_APP_KEYCLOAK_PROVIDE_VARIABLE, keycloak)
app.use(store)
await store.dispatch('keycloakStore/fillRoles', keycloak.realmAccess.roles)
app.use(router)
app.mount('#app')
}
}).catch((e) => {
console.log('Serwer lezy: ' + e)
})
I have the above code in my main.js file. This runs the keycloak subpage with login/register. If someone succesfully logs in, my Vue app starts. Now, instead of the above, I’d like to make it so the Vue app starts regardless of the person being logged in and the keycloak screen is ONLY launched if someone clicks a specified button in the UI. I’ve searched examples on the net, but i can only find ones that run keycloak on application start. Can someone help?
Turn onLoad value from 'login-required' to 'check-sso'. This option will only verify if the user is logged in without redirecting the user to login, and setup authentication properties acordingly.
Then you can call keycloak.login(), for example in your code. Together with route guards if necessary.
Also, put the creation of the app out of the else block, because it will not load if the user is not logged in when you have 'check-sso'.
I am trying to build firebase authentication for my react app..After I sign in I am trying to update the displayName and then redirect..On the redirected page I am trying to greet the user by fetching the display name saved while signing up with firebase..This page works properly immediately after I redirect but if I reload this page then it is not able to show the displayName and throws this error:
TypeError: Cannot read property 'displayName' of null
This is the function which gets triggered when signup button is clicked..
const signup = async () => {
try{
await firebaseApp.auth().createUserWithEmailAndPassword(email, password)
await firebaseApp.auth().currentUser.updateProfile({displayName:username})
console.log(firebaseApp.auth().currentUser)
if (!firebaseApp.auth().currentUser){
setLoading(true)
}
history.push('/home')
}catch (error){
alert(error.message)
}
}
This is the JSX of the page which is being redirected to by signup page:
<div className="greetings">
Good Evening {firebaseApp.auth().currentUser.displayName}
</div>
Why is this issue happening and how to resolve it?
firebaseApp.auth().currentUser is always null when a page first loads. It won't contain a User object until some time later, after the SDK is able to load and verify the auth token for that user. Instead of using currentUser, you should set up an auth state observer as shown in the documentation. This observer will get invoked as soon as the User object is known.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
// ...
} else {
// User is signed out.
// ...
}
});
You can use the results of this observer function to know when the user is signed in or signed out over time. To learn more about how it works, read this blog post.
I upgraded the version of Firebase for my app from 3.5.0 to 4.1.3 and noticed that the onAuthStateChange callback function is no longer called after a user successfully signs in for the first time after verifying their email address.
The app is written in JavaScript.
These are the relevant sections of my code:
Callback setup
firebase.auth().onAuthStateChanged(onAuthStateChange);
Callback
function onAuthStateChange (user) {
console.log(user); // Not appearing in console
}
Sign in
firebase.auth().signInWithEmailAndPassword(email, password)
.then(function (user) {
console.log("signInWithEmailAndPassword success"); // This appears in the console
})
.catch(function(error) {
console.log("signInWithEmailAndPassword", error);
self.signInError = error.message;
$timeout(function () {
$scope.$apply();
});
});
Edit - these are the steps to reproduce the problem (the typical action of a user of my app):
User downloads and launches app
User registers with email and password
App sends email verification email
User receives verification email and clicks on link
User goes to sign in page of app
User signs in triggering the console.log("signInWithEmailAndPassword success");
onAuthStateChanged callback is not called
For development and testing purposes (not what a user would do but I have done)
User reloads the app
User is now in the app
User signs out of the app
User signs in to the app triggering the console.log("signInWithEmailAndPassword success");
onAuthStateChanged callback is called
The problem is that auth().createUserWithEmailAndPassword() does in fact log in a type of user in.
You will find that if you type
firebase.auth().onAuthStateChanged(user => {
console.log("onAuthStateChanged()");
that createUserWithEmailAndPassword() does trigger the console log. However, there seems to be no valid "user" object, which would explain why nothing appears for you since you are only logging the user.
I ran into the exact same problems. At the sendEmailverification() step notice how it does require you to use auth().currentUser, signalling there must be some sort of user signed in (I am not sure how firebase handles the difference between email verified users and non-verified users behind the scenes)
You can simply called the signOut() function after sending the email verification and it should allow the onAuthStateChanged() function to call when logging in for the first time (without reloading the app)
firebase.auth().currentUser.sendEmailVerification()
.then(() => {
console.log("Email verification sent");
firebase.auth().signOut().then(() => {
console.log("Signed out!");
}).catch((err) => {
console.log("Error signing out!", err);
});
It is rather confusing that you can actually "Log in" successfully without causing a change in AuthStateChanged or returning any errors.
TLDR: Remember to use the auth().signOut() function after sending the email verification.
Try this way, i hope it'll work
firebase.auth().onAuthStateChanged(function(user){
console.log(user);
})