Using Firebase reauthenticate
Asked Answered
M

8

20

I'll appreciate assistance with how to reauthenticate a user in Firebase. I wonder if it makes any sense adding all these great features if the documentation doesn't explain how to use it:

Currently, this is what I'm trying, and it ain't working. Errors as cannot read property 'credential' of undefined

In constructor:

  constructor(@Inject(FirebaseApp) firebaseApp: any) {
    this.auth = firebaseApp.auth();
    console.log(this.auth);
  }

then the function

changePassword(passwordData) {
    if(passwordData.valid) {
      console.log(passwordData.value);
      // let us reauthenticate first irrespective of how long
      // user's been logged in!

      const user = this.auth.currentUser;
      const credential = this.auth.EmailAuthProvider.credential(user.email, passwordData.value.oldpassword);
      console.log(credential);
      this.auth.reauthenticate(credential)
        .then((_) => {
          console.log('User reauthenticated');
          this.auth.updatePassword(passwordData.value.newpassword)
            .then((_) => {
              console.log('Password changed');
            })
            .catch((error) => {
              console.log(error);
            })
        })
        .catch((error) => {
          console.log(error);
        })
    }
  }
Mashburn answered 5/10, 2016 at 11:35 Comment(4)
Were you able to resolve it? I'm running into the same issues.Harslet
@Harslet You tried Frank's answer? You should call the reauthenticate on the user, not the auth. Maybe it now would work, because it never did for me.Mashburn
actually, it did work. I was having the same issue where EmailAuthProvider was undefined. What I had to do was "cast" firebase to any: var fb: any = firebase; var credential = fb.auth.EmailAuthProvider.credential(email, password);Harslet
Their documentation are awful in places. You'd think with their expertise, knowledge, experience and manpower that they would have amazing documentation :/Logwood
E
22

The reauthenticate() method is called on a firebase.User, not on firebase.auth.Auth itself.

var user = firebase.app.auth().currentUser;
var credentials = firebase.auth.EmailAuthProvider.credential('[email protected]', 'firebase');
user.reauthenticate(credentials);

Update (July 2017):

There are some breaking change in the 4.0 version of the Firebase Web SDK. From the release notes:

BREAKING: firebase.User.prototype.reauthenticate has been removed in favor of firebase.User.prototype.reauthenticateWithCredential.

As far as I can tell the reauthenticateWithCredentialis a drop-in replacement for the old method.

Eckman answered 5/10, 2016 at 14:21 Comment(9)
Anything difference between your code and mine? I have widely open eyes trying to figure out how different your code is from mine, but I can't.Mashburn
You call this.auth.reauthenticate, where this seems to refer to firebase.auth(). I call user.reauthenticate on the user.Eckman
Okay, firebase.auth.EmailAuthProvider gives me an undefined. In full, if I do this: firebaseApp.auth.EmailAuthProvider, I get an undefined. Is the FirebaseApp actually exposing everything Firebase?Mashburn
Did a bit of reading about the FirebaseApp, and it doesn't look as mapping entirely to the native SDK FirebaseApp, unless I'm missing something.Mashburn
I have no idea what you're seeing there. I ran the code snippet I shared in a browser and it re-authenticates the user. Can you reproduce the problem in a jsbin/jsfiddle?Eckman
Please see the code here - github.com/seanmavley/AngularFire2-Authentication/blob/master/…Mashburn
Updated answer here, since apparently the moderator won't let me answer on this question (note that reauthenticate is deprecated): #35513913Tebet
UPDATE 2023: The link to firebase.User.prototype.reauthenticateWithCredential leads to a 404 page. For Firebase v8 docs, go here. For Firebase v9, apparently you need to import { reauthenticateWithCredential } from "firebase/auth";, refer here.Augite
Just found the section in the official docs for Firebase v9: hereAugite
C
2

Here's some code that enabled users to (a) reauthenticate in Firebase and (b) change their passwords after reauthenticating for me. I researched for about an hour while writing this, so hopefully it saves someone a minute.

Wrote in VueJS:

changePassword() {
            let self = this; // i use "self" to get around scope issues
            var user = firebase.auth().currentUser;
            var credential = firebase.auth.EmailAuthProvider.credential(
                this.$store.state.userId, // references the user's email address
                this.oldPassword
            );

            user.reauthenticateWithCredential(credential)
                .then(function() {
                    // User re-authenticated.
                    user.updatePassword(self.newPassword) 
                        .then(function() {
                            console.log("Password update successful!");
                        })
                        .catch(function(error) {
                            console.log(
                                "An error occurred while changing the password:",
                                error
                            );
                        });
                })
                .catch(function(error) {
                    console.log("Some kinda bug: ", error);
                    // An error happened.
                });
Crankpin answered 26/11, 2019 at 1:45 Comment(0)
A
1

Slight changes as of May 2019, see more details here. Code is as follows:

var user = firebase.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(user.email, password);

// Prompt the user to re-provide their sign-in credentials
return user.reauthenticateWithCredential(credential);
Adenoma answered 10/12, 2019 at 12:40 Comment(0)
C
1

Call changeEmail("new email","password") in onPressed directly to update the user email with no reauthentication required error

RaisedButton(
  onPressed: () {
    changeEmail(_emailController.text, _passwordController.text);
  }              

 Future<void> changeEmail(String email, String password) async {
   User user = await FirebaseAuth.instance.currentUser;
  print(email);
  print(password);
  try {
    try {
      var authResult = await user.reauthenticateWithCredential(
        EmailAuthProvider.getCredential(
          email: user.email,
          password: password,
        ),
      );
      user.updateEmail(email).then((_) {
        print("Succesfull changed email");
        _backthrow();
      }).catchError((error) {
        showAlertDialog(context, error.message);
        print("email can't be changed" + error.toString());
      });
      return null;
    } catch (e) {
      print("2");
    }
  } catch (e) {
    print(e.message);
    showAlertDialog(context, e.message);
  }
}
Centrobaric answered 24/12, 2020 at 13:17 Comment(0)
C
1

This is how I re-authenticate a user in Firebase:

import { getAuth, EmailAuthProvider, reauthenticateWithCredential } from "firebase/auth";

const auth = getAuth()

const reauthenticateUser = async (email, password) => {
  const user = auth.currentUser;
  try {
    const credential = EmailAuthProvider.credential(email, password);
    await reauthenticateWithCredential(user, credential)
  } catch (error) {
    Alert.alert("Error", "The email or password is incorrect. Please try again.")
  }
}
Cavern answered 9/2, 2023 at 0:48 Comment(0)
S
0

Hers a full example how to reauthenticate with Firebase

var pass = "abcdefg";
var user = firebase.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(user.email, pass);

user.reauthenticateWithCredential(credential).then(() => {
    console.log("Its good!");
}).catch((error) => {
    console.log(error);
});
Softwood answered 19/7, 2021 at 21:45 Comment(0)
S
0

Since 2021: If you use Firebase JS API 9.x (the tree shakable version) this is the most recent way:

https://cloud.google.com/identity-platform/docs/web/reauth

With credentials

import { getAuth, reauthenticateWithCredential } from "firebase/auth";

const auth = getAuth();
const user = auth.currentUser;

// todo for you: prompt the user to re-provide their sign-in credentials
const credential = promptForCredentials();

reauthenticateWithCredential(user, credential).then(() => {
  // ...
}).catch((error) => {
  // ...
});

With popup

import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";

const auth = getAuth();
// todo for you: change to appropriate provider
const provider = new OAuthProvider('apple.com');

reauthenticateWithPopup(auth.currentUser, provider)
  .then((result) => {
    // ...
  })
  .catch((error) => {
    // ...
  });
Senna answered 1/11, 2022 at 17:14 Comment(0)
P
-1

I was getting that re-authentication error auth/requires-recent-login when saving the primary email.
I couldn't figure out how to implement that poorly documented reauthenticateWithCredential(credential) method, so, I simply logged-out the user and redirected to login page. It's a hack but It works like charm!

firebase.auth().signOut();
Proteose answered 24/6, 2020 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.