I have email link sign-in setup in my web app and it works fine. However, I need to reauthenticate a user before performing a certain action.
I am using the following code to reauthenticate:
let credential = firebase.auth.EmailAuthProvider.credentialWithLink(userEmail, window.location.href);
firebase.auth().currentUser.reauthenticateWithCredential(credential).then(function (usercred: any) {
console.log('Reauthentication test successful.');
}).catch(function (error: any) {
console.log('Reauthentication test failed.');
});
However, the credential throws an error every time:
code: "auth/argument-error"
message: "Invalid email link!"
This is even if I try changing the URL. The url is authorized in the console, and is https (I was testing on localhost at first and thought maybe that was the issue).
Any ideas?
I had the same issue and the documentation is kind of vague in the process. I did not want to use already existing UI solutions (đŸ˜…) so I had to figure it out.
Here is the documentation snippet:
import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth";
// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
email, window.location.href);
// Link the credential to the current user.
const auth = getAuth();
linkWithCredential(auth.currentUser, credential)
.then((usercred) => {
// The provider is now successfully linked.
// The phone user can now sign in with their phone number or email.
})
.catch((error) => {
// Some error occurred.
});
The code window.location.href
supposes that you are opening a link from an email link sign in
It's not too different from the others, email link process, where you have to trigger an email being sent either from the client side or a server.
I would have the page to handle the other modes (password reset, ...) and also this specific logic to handle new authentication or just re-authentication on page load.
here is an exemple on Angular (Typescript) based on the documentation
// app.component.ts
ngAfterViewInit() {
const currentUrl = window.location.href;
if (isSignInWithEmailLink(this.authService.auth, currentUrl)) {
const isLoggedIn = !!this.user?.uid;
let email = isLoggedIn
? this.user?.email
: window.localStorage.getItem("emailForSignIn");
if (!email) {
email = window.prompt("Please provide your email for confirmation");
}
if (email && validateEmail(email)) {
try {
// --> important !
if (isLoggedIn) {
const credential = EmailAuthProvider.credentialWithLink(email,currentUrl);
await reauthenticateWithCredential(this.user, credential)
} else {
await signInWithEmailLink(
this.authService.auth,
email,
currentUrl
);
}
window.localStorage.removeItem("emailForSignIn");
this.router.navigateByUrl("/login");
// console.log(userCredential);
} catch (e) {
console.log(e);
// Some error occurred, you can inspect the code: error.code
// Common errors could be invalid email and invalid or expired OTPs.
this.toastr.error(getTranslation(e.code), "Error");
}
} else {
this.toastr.error("Please enter a valid email", "Error");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With