19

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);
        })
    }
  }
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
KhoPhi
  • 9,660
  • 17
  • 77
  • 128
  • Were you able to resolve it? I'm running into the same issues. – MK_Dev Jan 25 '17 at 23:20
  • @MK_Dev 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. – KhoPhi Jan 26 '17 at 01:30
  • 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); – MK_Dev Jan 26 '17 at 01:39
  • 1
    Their documentation are awful in places. You'd think with their expertise, knowledge, experience and manpower that they would have amazing documentation :/ – TheCarver Oct 17 '20 at 21:08

8 Answers8

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('puf@firebaseui.com', '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.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 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. – KhoPhi Oct 05 '16 at 17:01
  • You call `this.auth.reauthenticate`, where `this` seems to refer to `firebase.auth()`. I call `user.reauthenticate` on the user. – Frank van Puffelen Oct 05 '16 at 17:03
  • 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? – KhoPhi Oct 05 '16 at 18:12
  • 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. – KhoPhi Oct 05 '16 at 20:22
  • 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? – Frank van Puffelen Oct 06 '16 at 09:09
  • Please see the code here - https://github.com/seanmavley/AngularFire2-Authentication/blob/master/app/dashboard/child.component.ts – KhoPhi Oct 06 '16 at 13:17
  • Updated answer here, since apparently the moderator won't let me answer on this question (note that reauthenticate is deprecated): https://stackoverflow.com/questions/35513413/angular-how-to-display-number-always-with-2-decimal-places-in-input/44124785#44124785 – maudulus May 23 '17 at 15:08
  • UPDATE 2023: The link to `firebase.User.prototype.reauthenticateWithCredential` leads to a 404 page. For Firebase v8 docs, go [here](https://firebase.google.com/docs/reference/js/v8/firebase.User#reauthenticatewithcredential). For Firebase v9, apparently you need to `import { reauthenticateWithCredential } from "firebase/auth";`, refer [here](https://stackoverflow.com/questions/69186075/error-with-reauthenticatewithcredential-get-error-typeerror-credential-getreau?rq=3). – Irfan Zainudin Jul 10 '23 at 20:34
  • Just found the section in the official docs for Firebase v9: [here](https://firebase.google.com/docs/auth/web/manage-users) – Irfan Zainudin Jul 10 '23 at 21:54
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.
                });
Roly Poly
  • 489
  • 1
  • 9
  • 19
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);
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);
  }
}
Striped
  • 2,544
  • 3
  • 25
  • 31
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.")
  }
}
Green
  • 507
  • 10
  • 20
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);
});
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) => {
    // ...
  });
RiZKiT
  • 2,107
  • 28
  • 23
-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();
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225