121

The (unclear) example in the new docs:

var user = firebase.auth().currentUser;
var credential;
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {

How should I create this credential object?

I tried:

  • reauthenticateWithCredential(email, password) (like the login method)
  • reauthenticateWithCredential({ email, password }) (the docs mention one argument only)

No luck :(

PS: I don't count the hours wasted searching for relevant info in the new docs... I miss so much the fabulous firebase.com docs, but wanted to switch to v3 or superior for firebase.storage...

Pandaiolo
  • 11,165
  • 5
  • 38
  • 70

7 Answers7

241

I managed to make it work, docs should be updated to include this for who does not want to spend too much time in the exhaustive-but-hard-to-read API reference.

Firebase 8.x

The credential object is created like so:

const user = firebase.auth().currentUser;
const credential = firebase.auth.EmailAuthProvider.credential(
    user.email, 
    userProvidedPassword
);
// Now you can use that to reauthenticate
user.reauthenticateWithCredential(credential);

Firebase 9.x

(Thanks @Dako Junior for his answer that I'm adding here for exhaustivity)

import {
    EmailAuthProvider,
    getAuth,
    reauthenticateWithCredential,
} from 'firebase/auth'

const auth = getAuth()
const credential = EmailAuthProvider.credential(
    auth.currentUser.email,
    userProvidedPassword
)
const result = await reauthenticateWithCredential(
    auth.currentUser, 
    credential
)
// User successfully reauthenticated. New ID tokens should be valid.

Note

Some people asked about userProvidedPassword, if it was some sort of stored variable from the first login. It is not, you should open a new dialog/page with a password input, and the user will enter their password again.

I insist that you must not try to workaround it by storing user password in cleartext. This is a normal feature for an app. In GMail for example, sometimes your session expires, or there is a suspicion of hack, you change location, etc. GMail asks for your password again. This is reauthentication.

It won't happen often but an app using Firebase should support it or the user will be stuck at some point.

Pandaiolo
  • 11,165
  • 5
  • 38
  • 70
  • I was on the way. :) – adolfosrs Jun 14 '16 at 12:51
  • 5
    Great to hear that you found the solution! I'll add a note to update/clarify the docs. And keep in mind that there's also a feedback button on every page for that specific purpose. :-) – Frank van Puffelen Jun 14 '16 at 13:44
  • Cool, +1 for the feedback button (didn't see at first) – Pandaiolo Jun 14 '16 at 14:05
  • @Pandaiolo -- Thanks for this. I too have spent several hours trying to figure this out. – Chris Carson Jun 17 '16 at 14:23
  • What is wrong here: `var currentCredential = firebaseAuth.EmailAuthProvider.credential(vm.currentAuth.email, vm.oldPassword); vm.currentAuth.reauthenticate(currentCredential) .then(function() { Database.updateUserPassword(vm.newPassword); }, function(error) { console.error('[Account]', error); });` – gcfabri Oct 14 '16 at 19:43
  • `updatePassword` is a `User` method. So in your code I think that would be: `firebase.auth().currentUser.updatePassword(vm.newPassword)`. Also be careful in your code if you use promises or callbacks, not sure you have it right because code in SO comments is pretty hard to read. – Pandaiolo Oct 17 '16 at 10:03
  • For example with promises: `firebase.auth().currentUser.reauthenticate(credentialsObject).then(function() { return firebase.auth().currentUser.updatePassword(newPassword); }).then(function() { /* We're done here */ }).catch(function(error) { /* deal with error here */ });` – Pandaiolo Oct 17 '16 at 10:06
  • 50
    3 years later and the docs still need to be updated! Thank you for saving me time. – Ramtin Soltani Feb 01 '19 at 14:16
  • The key to this, in an Ionic/Angular project is to get the import of firebase right. import { AngularFireAuth } from '@angular/fire/auth'; import { User } from 'firebase'; import * as firebase from 'firebase/app'; – Craig Shearer Oct 26 '19 at 10:28
  • 23
    4 years later... yet the doc still "exhaustive-but-hard-to-read" – Nik Nov 23 '19 at 02:49
  • What is "userProvidedPassword"? I cant believe I need to store the user pwd, (and I doubt Firestore let me do that) – l1b3rty Mar 02 '20 at 15:48
  • 1
    @Oliver, this codes relates to when the user needs to reauthenticate (hence the name of the method). In that event, like with the sign-in form, they need to provide their password again. Never store user passwords yourself. (or, well, do it properly but in that case you aren't using Firebase auth :) ) – Pandaiolo Mar 03 '20 at 16:19
  • Isn't that bad, that `firebase` asks for user password, to reauthenticate user? That means that developer should save it in `AsyncStorage`, which is NOT advised… – Fotios Tsakiris Jan 04 '22 at 08:17
  • 1
    @FotiosTsakiris you should definitely not trying to workaround it by storing user password in cleartext, this seems like a normal feature for an app. In GMail for example, sometimes your session expires, or there is a suspicion of hack, you change location, etc. GMail asks for your password again. This is reauthentication. It won't happen often but an app using Firebase should support it or the user will be stuck at some point. Adding this to the answer for clarity. – Pandaiolo Jan 05 '22 at 09:52
  • @Pandaiolo So, every time the app is refreshed, the user should input a password. Well, that seems reasonable. Thanks! – Fotios Tsakiris Jan 08 '22 at 10:23
  • 5 1/2 years later... – stevehs17 Feb 10 '22 at 03:32
40

Complete answer - you can use the following:

var user = firebase.auth().currentUser;
var credentials = firebase.auth.EmailAuthProvider.credential(
  user.email,
  'yourpassword'
);
user.reauthenticateWithCredential(credentials);

Please note that reauthenticateWithCredential is the updated version of reauthenticate()

maudulus
  • 10,627
  • 10
  • 78
  • 117
  • 4
    Thanks for adding the third line that is missing from the accepted answer – tim-phillips May 27 '17 at 21:20
  • 1
    @Oliver the password should be the one that already exists with that email. – maudulus Mar 02 '20 at 17:22
  • Not sure that it was @Sandokan, seeing here: https://firebase.google.com/docs/reference/js/firebase.User#reauthenticatewithcredential - where did you see it deprecated? – maudulus Nov 27 '20 at 16:33
  • @Sandokan I believe you are mistaken - reauthenticateAndRetrieveDataWithCredential is deprecated: https://firebase.google.com/docs/reference/js/firebase.User#reauthenticateandretrievedatawithcredential – maudulus Nov 28 '20 at 15:45
  • @maudulus. Yes. you are right. In my case, it was firebase version issue. I was using firebase5.7. *firebase.User.prototype.reauthenticateWithCredential is deprecated. Please use firebase.User.prototype.reauthenticateAndRetrieveDataWithCredential instead.* – Sandokan Nov 30 '20 at 09:48
6

With the new firebase version 9.*

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

const auth = getAuth();


let credential = EmailAuthProvider.credential(
                  auth.currentUser.email,
                  password
                );

reauthenticateWithCredential(auth.currentUser, credential)
.then(result => {
      // User successfully reauthenticated. New ID tokens should be valid.
    })
Dako Junior
  • 587
  • 6
  • 8
5

There are multiple methods to re-authenticat. See the refs: https://firebase.google.com/docs/reference/js/firebase.User

firebase
.auth()
.currentUser.reauthenticateWithPopup(new firebase.auth.GoogleAuthProvider())
.then((UserCredential) => {
    console.log("re-outh", UserCredential);
});

In case your app allows multiple authentication methods you might want to first find out what privider was used. You can do this by looking at the firebase.auth().currentUser.providerData array.

Jürgen Brandstetter
  • 7,066
  • 3
  • 35
  • 30
0

I agree that the documentation is not pretty clear on this. But looking a little deeper on the API reference I found firebase.auth.AuthCredential and this and I guess you should be looking to pass it to reauthenticate().

I'm guessing here but I would start trying to log the firebase.auth() to see if there is any credential object there.

I suppose it will look something like the following:

user.reauthenticate(firebase.auth().credential).then(function() {
adolfosrs
  • 9,286
  • 5
  • 39
  • 67
  • I managed to get it to work, I'm writing an answer. You forgot the email and password in your answer :) – Pandaiolo Jun 14 '16 at 12:46
0

Now there's a small change in the method since both posted answers are deprecated,

    val user = auth.currentUser
    user?.let { _user ->
        val credentials = EmailAuthProvider.getCredential(
            _user.email!!,
            "userPassword"
        )
        _user.reauthenticate(credentials).addOnCompleteListener { _reauthenticateTask ->
  }
Manoj Perumarath
  • 9,337
  • 8
  • 56
  • 77
-2
final FirebaseUser fireBaseUser = FirebaseAuth.getInstance().getCurrentUser();
AuthCredential credential = EmailAuthProvider.getCredential(fireBaseUser.getEmail(), storedPassword);
fireBaseUser.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
     @Override
     public void onComplete(@NonNull Task<Void> reAuthenticateTask) {
          if (!reAuthenticateTask.isSuccessful())
               ...
     }
});