disable firebase Auth State Persistence - javascript

I have this login function currently:
AuthorizationHome.doSignInWithEmailAndPassword(email, password)
.then(() => {
firebase.auth().onAuthStateChanged((user) => {
..........
But it basically keeps my session logged in even when I close my browser, restart my computer, it does it all. Because the user is able to manage their payments from my app, I need to make sure that if they close the browser, it logs them out.
Firebase docs tells me to do it like this:
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
.then(() => {
return firebase.auth().signInWithEmailAndPassword(email, password);
})
.catch((error) => {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
});
It is different then my original code, so I am not sure how to do this. I'm totally new to the way firebase works so I am a little confused.

Are you trying to execute firebase.auth().onAuthStateChanged after AuthorizationHome.doSignInWithEmailAndPassword(email, password) successfully resolves?
firebase
.auth()
.setPersistence(firebase.auth.Auth.Persistence.SESSION)
.then(() => {
return AuthorizationHome.signInWithEmailAndPassword(email, password).then(() => {
firebase.auth().onAuthStateChanged((user) => { /* do things */ });
});
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
That being said, you can probably run setPersistence(firebase.auth.Auth.Persistence.SESSION) as part of app initialization separately. It doesn't have to be run right before every execution of doSignInWithEmailAndPassword:
// app initialization
firebase
.auth()
.setPersistence(firebase.auth.Auth.Persistence.SESSION)
// somewhere else on demand
AuthorizationHome.doSignInWithEmailAndPassword(email, password)
.then(() => {
firebase.auth().onAuthStateChanged((user) => {
Hopefully that helps!

Related

Google signin with signInWithRedirect always takes me back to the login page

I'm having a hard time getting the Firebase signInWithRedirect with google to work. Below is the doc I've been looking at: https://firebase.google.com/docs/auth/web/google-signin.
I have a login page which contains a button. When the button is clicked it take you to google sign in page. However every time I sign in with google it redirects me back to the login page of my app. Part of the code is shown below:
login() {
const auth = getAuth();
signInWithRedirect(auth, provider);
console.log("AAA")
auth.onAuthStateChanged((user) => {
console.log("BBB")
if (user) {
this.$router.push('home')
} else {
getRedirectResult(auth)
.then((result) => {
console.log("WIN0")
// This gives you a Google Access Token. You can use it to access Google APIs.
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
console.log(token)
console.log(user)
console.log("WIN")
}).catch((error) => {
console.log("ERROR0")
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.customData.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
console.log(errorCode)
console.log(errorMessage)
console.log(email)
console.log(credential)
console.log("ERROR")
// ...
});
}
})
From the console, I only ever see the log AAA, but I don't see any other logs at all. What am I missing? Thank you.
I should also mention that I'm doing this in vue js but I don't think it matters.
So the problem was that I have onAuthStateChanged within the login function. Since the SignInWithRedirect takes to a different page and then redirects back to the page where it was called, in vue I basically moved the onAuthStateChanged to the mounted lifecycle hook.
mounted() {
auth.onAuthStateChanged((user) => {
console.log("BBB")
if (user) {
this.$router.push('home')
} else {
getRedirectResult(auth)
.then((result) => {
console.log("WIN0")
// This gives you a Google Access Token. You can use it to access Google APIs.
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
console.log(token)
console.log(user)
console.log("WIN")
}).catch((error) => {
console.log("ERROR0")
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.customData.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
console.log(errorCode)
console.log(errorMessage)
console.log(email)
console.log(credential)
console.log("ERROR")
// ...
});
}
})
}

Data not being saved in firestore

I'm making an app with React js and firebase. When signing Up, firebase create the user and makes the alert I want but the data I want to save in firestore is not being saved. If I use the hendleSighUp function without the checkUser, it works. What I'm doing wrong? Thank you, sorry to bother you.
const checkUser = async (avatar) => {
var docRef = fb.firestore().collection("links").doc(user2);
var doc = await docRef.get();
if (doc.exists) {
//invalidUsername(true);
console.log("error");
} else {
handleSignUp();
console.log("Working");
//history.push("/");
}
};
const handleSignUp = () => {
clearErrors();
fb.auth()
.createUserWithEmailAndPassword(email, password)
.then((userCredential) => {
// send verification mail.
userCredential.user.sendEmailVerification();
handleLogOut();
fb.firestore()
.collection("links")
.doc("Andres")
.set({ name: "Andres" });
alert("Email sent");
})
.catch((err) => {
switch (err.code) {
case "auth/email-already-in-use":
case "auth/invalid-email":
setEmailError(err.message);
break;
case "auth/weak-password":
setPasswordError("Contrasena debil");
break;
}
});
};
I would make the function async and use await while setting the document to make sure the promise is resolved and also as alert is synchronous do it'll will block any code execution until its dismissed. Because you are not using await the alert will trigger right away.
fb.auth()
.createUserWithEmailAndPassword(email, password)
.then(async (userCredential) => {
// ^^^^^
// send verification mail.
userCredential.user.sendEmailVerification();
handleLogOut();
await fb.firestore()
^^^^^
.collection("links")
.doc("Andres")
.set({ name: "Andres" });
alert("Email sent");
})

Firebase Anonymous User once upgraded

I'm implementing a workflow where every user using my app is an anonymous user until they sign-in/up (either email or Google).
To sign up, it's straightforward: I use linkWithPopup.
However, I had some issues with user signing in: I try to link them and, if I get the auth/credential-already-in-use error (happens if the user upgrades once, signs out and then try to sign in again), I sign them in.
firebase.auth().currentUser.linkWithPopup(provider).then(function (result) {
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
}).catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
if (errorCode === 'auth/credential-already-in-use') {
return firebase.auth().signInWithCredential(error.credential);
}
}).then((result) => {
return dispatch(loadContent(result.user.uid))
}).then(() => {
history.push('/');
});
The code above is working great and that's less hassle than doing it all by myself.
However, how do I remove the anonymous users which are created and orphan in case the user signs in?
I tried to make a reference to the old useless anonymous user and to delete it once the user is signed in (and so, changed its account) but it is obviously not working because the account changed and that would be a big security flaw if a user could delete another one...
I'm not very familiar with Firebase ecosystem, how should I handle that? Do I need to use a combination of Firebase Cloud Function and Firebase Admin SDK or is there a standard way of solving this problem?
It is quite simple. APIs on the user continue to work even if the user is not current.
const anonymousUser = firebase.auth().currentUser;
firebase.auth().currentUser.linkWithPopup(provider)
.then(function (result) {
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
}).catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
if (errorCode === 'auth/credential-already-in-use') {
return firebase.auth().signInWithCredential(error.credential);
}
}).then((result) => {
if (anonymousUser.uid !== result.user.uid) {
return anonymousUser.delete()
.then(() => {
return result;
});
}
return result;
}).then((result) => {
return dispatch(loadContent(result.user.uid))
}).then(() => {
history.push('/');
});

Firebase web sign out doesn't send any XHR

When setting up a simple form - 2 buttons with 2 functions to test firebase's auth, i have a problem with sign out.
The sign in function works perfect.
However, sign out doesn't send any XHR. Nothing, nada. No errors.
But the promise resolves.
The console logs 'Signed Out'.
What am i doing wrong?
Thanks!
function signIn() {
firebase.auth().signInWithEmailAndPassword('email#email.com', 'password')
.then(() => {
console.log('Logged in')
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorMessage)
});
}
function signOut() {
firebase.auth().signOut().then(() => {
console.log('Signed out!')
}).catch((error) => { console.log(error) });
}
Signing out just involves "forgetting" the refresh token that's used to keep the user signed in persistently over time. The server doesn't need to be notified that this happened.

Firebase getIdToken not working

I'm makeing tests with Firebase Authentication from javascript client and I'm trying to retrieve the idToken with retrieve id tokens on clients documentation
I think I'm forgetting something basic.
A user is logged in with Google
The code is just i've seen in other posts and in the documentation. And the result is in the comments.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log(user); // this is shown. Firebase user and provider data
console.log(user.uid); // Shown
firebase.auth().user.getIdToken().then(function(idToken) {
console.log(idToken+'--'); // Nothing happens. No errors and the function not continues
});
console.log(user.uid); // Nothing happens
}
})
Thanks
EDIT:
if I add anything wrong nothing happens too. for example if I add an alert it shows the alert but if I have a mistake, for example alter() not shows any error. Added catch and nothing too
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
alter() // Nothing happens and the function stop
console.log(user); // this is shown. Firebase user and provider data
console.log(user.uid); // Shown
firebase.auth().user.getIdToken().then(function(idToken) {
console.log(idToken+'--'); // Nothing happens. No errors and the function not continues
}).catch(function(error) {
console.log(error+'--'); // Nothing
});
console.log(user.uid); // Nothing happens
}
})
firebase.auth().user doesn't have the user in that moment yet. You have to use the user from firebase.auth().onAuthStateChanged directly like this:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log(user); // It shows the Firebase user
console.log(firebase.auth().user); // It is still undefined
user.getIdToken().then(function(idToken) { // <------ Check this line
console.log(idToken); // It shows the Firebase token now
});
}
});
You can only use firebase.auth().user after firebase.auth().onAuthStateChanged is completed and outside of its scope, otherwise it will be undefined.
firebase.auth().currentUser is synchronous. We can make it asynchronous by subscribing to the auth observable instead.
Depending on the library we’re using, the JavaScript SDK has onAuthStateChanged() and AngularFire2 has both authState() onAuthStateChanged().
// For AngularFire:
private afAuth: AngularFireAuth,
afAuth.authState.subscribe(user => {
if (user) {
user.getIdToken(true).then(idToken => {
// ...
});
}
});
// or
this.afAuth.auth.onAuthStateChanged(user => {
if (user) {
user.getIdToken(true).then(idToken => {
//...
});
}
});
// For the JS SDK
firebase.auth().onAuthStateChanged(user => {
if (user) {
user.getIdToken(true).then(idToken => {
// ...
});
}
});
For firebase versions greater than V8. We directly have to call the functions of auth.
const loginWithGoogle = () => {
const googleProvider = new GoogleAuthProvider();
signInWithPopup(auth, googleProvider)
.then((userCredentials) => {
if (userCredentials) {
setIsUserAuthenticated(true);
window.localStorage.setItem('authorization', true);
console.log(userCredentials);
userCredentials.user.getIdToken().then((token) => {
setToken(token);
console.log(token);
});
}
})
.catch((err) => {
console.log(err.message);
});
};

Categories