Повторная аутентификация Firebase и связывание электронной почты для пользователей, прошедших аутентификацию по телефону

Когда пользователи регистрируются, они используют Телефонную аутентификацию. После некоторого использования приложения им рекомендуется привязать (адрес электронной почты и пароль) к своей существующей учетной записи.

Процесс связывания завершается неудачно из-за ошибки (auth / requires-Recent-login.) Мой код следует.

// The following generates the error: [auth/requires-recent-login] This operation is sensitive and requires recent authentication. Log in again before retrying this request.
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);

const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential); 

Я понимаю, что чтобы исправить эту ошибку, мне нужно вызвать reauthenticateWithCredential () перед связыванием. Однако я не хочу просить пользователя снова войти в систему (получить и ввести проверочный код). Возможно ли это вообще?

Я попытался передать результат currentUser.getIdToken(true) в PhoneAuthProvider.credential(). Не уверен, что это правильно. В любом случае, это сгенерировало ошибку (Невозможно создать PhoneAuthCredntial без verifyProof, sessionInfo, временного подтверждения или идентификатора регистрации.).

Мой код следует.

// The following works: 
const accessToken = await firebase.auth().currentUser.getIdToken(true); 

// The following works: 
const currentCredential = firebase.auth.PhoneAuthProvider.credential(accessToken); 

// The following generates the error: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID.
const abc = await firebase.auth().currentUser.reauthenticateWithCredential(currentCredential); 

// The following is never reached:  
const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);

const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential); 

Спасибо за ваши усилия и время, чтобы помочь мне ...


person Bilal Abdeen    schedule 11.11.2019    source источник
comment
Я столкнулся с той же проблемой, но у меня есть один вопрос: я использую аутентификацию телефона и вручную устанавливаю тестовый номер в консоли firebase. Поэтому, когда я устанавливаю другие номера, я не могу получить какой-либо проверочный код в виде SMS, так что это работает с вами?   -  person DevAS    schedule 12.11.2019
comment
@DevAS Я не уверен, что правильно понял ваш вопрос. Я все равно постараюсь на него ответить. Насколько я понимаю, вы вообще не можете получать SMS на эмуляторах Android. Если вы хотите попробовать получить код подтверждения по SMS, вам необходимо развернуть приложение на реальном устройстве. Отвечает ли это на ваш вопрос?   -  person Bilal Abdeen    schedule 12.11.2019
comment
Может быть, что я хочу сказать, у меня есть экран входа в систему, и я использую свой фактический номер для входа в систему, и firebase должна отправить мне SMS-сообщение, содержащее проверочный код, верно? Но я ничего не могу получить на свой мобильный, это отладочная версия моего приложения, которая не выпускается.   -  person DevAS    schedule 12.11.2019
comment
@DevAS Проверьте это: firebase.google.com/docs/auth/web/ phone-auth   -  person Bilal Abdeen    schedule 12.11.2019


Ответы (1)


Важная информация:

  1. firebase.auth (). currentUser.reauthenticateWithCredential (учетные данные) требует учетных данных атрибута
  2. Для пользователей, которые вошли в систему с помощью номера телефона, я не смог найти способ получить эти учетные данные при необходимости. Кстати, это возможно для пользователей, которые вошли в систему с помощью других провайдеров. , например Facebook.
  3. Однако для пользователей, которые входят в систему с помощью номера телефона, эти учетные данные можно получить во время процесса входа. Отметьте https://firebase.google.com/docs/auth/web/phone-auth.
  4. Итак, я решил сохранить учетные данные пользователя на его устройстве во время процесса входа в систему. Для этого я использую Redux и Redux-Persist.

Мой код после исправления.

// This is an extract from the login script: 
firebase.auth().signInWithPhoneNumber(phoneNo)
    .then(confirmResult => {
        dispatch({ type: "PhoneNo_accepted", payload: { confirmResult: confirmResult } }); 
    })
    .catch(error => { 
        dispatch({ type: "display_message", payload: { messageText: `Phone Number Error: ${error.message}` } });
    });

// Change#1. The following statement is a NEW step, which I added to get the credential during the login process. 
const credential = firebase.auth.PhoneAuthProvider.credential(state.confirmResult.verificationId, state.codeInput);

state.confirmResult.confirm(state.codeInput)
    .then( (user) => {
        // Change#2. The following function would save the credential to the app's state, e.g. using Redux
        _onAuthComplete(user, credential);
    })
    .catch( error => { 
        dispatch({ type: "display_message", payload: { messageText: `Verification Code Error: ${error.message}` } });
    });

// // // 

// This is an extract from the linking script: 
// Change#3. props.credential is the credential, which was saved to the app's state. 
await firebase.auth().currentUser.reauthenticateWithCredential(props.credential);

const emailCredential = firebase.auth.EmailAuthProvider.credential(state.email, state.password);
const newCredential = await firebase.auth().currentUser.linkWithCredential(emailCredential); 

person Bilal Abdeen    schedule 12.11.2019
comment
Можете ли вы проверить этот вопрос, пожалуйста? native "> stackoverflow.com/questions/59017495/ - person Oliver D; 24.11.2019