Проверьте, существует ли пользователь Firebase Facebook без создания пользователя, начиная с анонимного пользователя - PullRequest
0 голосов
/ 04 июня 2018

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

Если я использую Auth.signInAndRetrieveDataWithCredential, я ожидал ошибку " auth / user-not-found ", но вместо этогопользователь просто создан.Это ошибка или ожидается?

let credential = firebase.auth.FacebookAuthProvider.credential(
        event.authResponse.accessToken)
    firebase.auth().signInAndRetrieveDataWithCredential(credential).then( (userCredential) => {
        let user = userCredential.user
        app.debug("DEBUG: Existing user signed in:"+user.uid)
        this.loginSuccess(user)
    }).catch( (err) => {
        app.error("ERROR re-signing in:"+err.code)
        $("#login_status_msg").text(err)
    })

Если я использую вместо этого User.reauthenticateAndRetrieveDataWithCredential, я получаю ошибку " auth / user-mismatch ", которая имеет смысл, поскольку пользователь в настоящее время является анонимным.Однако я ожидал, что вместо этого может быть выдано «auth / user-not-found», если учетные данные не существуют, но этого не происходит.

Я не вижу способа взять моего анонимапользователь, попросите его войти в систему через Facebook, а затем посмотреть, не связан ли другой пользователь с этими учетными данными Facebook, не создавая пользователя, если он не существует.

Если вам интересно, почему?Мой сценарий таков: система разрешает анонимным пользователям

  1. Пользователь входит в систему, а затем преобразовывается в зарегистрированного пользователя, зарегистрировавшись в Facebook.
  2. Удаление приложения
  3. Приложениепереустановить
  4. Пользователь запускает приложение и изначально является анонимным.
  5. Они снова пытаются войти в систему через Facebook.На данный момент я хочу помешать им создать пользователя, если у него его еще нет.Если у них уже есть идентификатор пользователя, код работает нормально и заменяет его анонимный идентификатор учетной записи на оригинальный идентификатор пользователя, который является хорошим.

Ответы [ 4 ]

0 голосов
/ 06 января 2019

То, что я сделал, чтобы решить эту проблему, не полагаясь на вызов linkAndRetrieveDataWithCredential для сбоя и используя блок catch для входа в систему уже существующего пользователя, - это сохранение поля userID, которое возвращает getCurrentAccessToken.

const { userID } = data;
this.props.setFacebookId(userID); // saves the userID on the server

Позже я смогу проверить, существует ли этот userID в следующий раз, когда пользователь зарегистрируется на Facebook.

0 голосов
/ 04 июня 2018

Вы можете использовать linkAndRetrieveDataWithCredential:

let credential = firebase.auth.FacebookAuthProvider.credential(
    event.authResponse.accessToken);
anonymousUser.linkAndRetrieveDataWithCredential(credential).then( (userCredential) => {
  // Firebase Auth only allows linking a credential if it is not
  // already linked to another account.
  // Now the anonymous account is upgraded to a permanent Facebook account.
}).catch( (err) => {
  // Check for code: auth/credential-already-in-use
  // When this error is returned, it means the credential is already
  // used by another account. 
})
0 голосов
/ 12 июля 2018

Я нашел решение!Это было не слишком сложно реализовать, но это кажется хакерским.

Итак, мы знаем, что при использовании signInAndRetrieveDataWithCredential(cred) для входа в Facebook учетная запись создается , даже если она еще не существует. Чтобы решить эту проблему, нам нужно убедиться, что мы обрабатываем следующие три вещи:

  1. Определить, является ли учетная запись новой
  2. Удалить текущую учетную запись, созданную firebase
  3. Выдает ошибку, чтобы выйти из текущего потока и вернуться туда, где вы были раньше.

Я только что внедрил и протестировал это решение, и, похоже, оно прекрасно работает:

// ... do your stuff to do fb login, get credential, etc:
const userInfo = await firebase.auth().signInAndRetrieveDataWithCredential(credential)

// userInfo includes a property to check if the account is new:
const isNewUser = _.get(userInfo, 'additionalUserInfo.isNewUser', true)

// FIRST, delete the account we just made.
// SECOND, throw an error (or otherwise escape the current context.
if (isNewUser) {
  firebase.auth().currentUser.delete()
  throw new Error('Couldn\'t find an existing account.')
}

// If the user already exists, just handle normal login
return userInfo.user

Причина, по которой я это сделал, состояла в том, чтобы убедиться, что пользователи должны были пройти через «создать учетную запись» в моем приложении.Ваш случай также будет очень легко реализовать, например:

let credential = firebase.auth.FacebookAuthProvider.credential(event.authResponse.accessToken)

firebase.auth().signInAndRetrieveDataWithCredential(credential)
  .then(userCredential => {
    const isNewUser = userCredential.additionalUserInfo.isNewUser
    if (isNewUser) {
      firebase.auth().currentUser.delete()
      // The following error will be handled in your catch statement
      throw new Error("Couldn't find an existing account.")
    }
    // Otherwise, handle login normally:
    const user = userCredential.user
    app.debug("DEBUG: Existing user signed in:"+user.uid)
    this.loginSuccess(user)
  }).catch( (err) => {
    app.error("ERROR re-signing in:"+err.code)
    $("#login_status_msg").text(err)
  })
0 голосов
/ 04 июня 2018

Вы можете использовать метод fetchSignInMethodsForEmail, чтобы проверить, связано ли конкретное письмо с конкретным провайдером или нет.Сделав это, вы сможете проверить, содержит ли SighInMethods электронная почта, связанная с вашим пользователем, Facebook.com или нет.

Ниже приведен пример того, как я управляю этими делами в моем приложении.,Я использую RxJavaWrapper в своем коде, но вы поймете, как им управлять:

 RxFirebaseAuth.fetchSignInMethodsForEmail(authInstance, email)
                .flatMap { providerResult ->
                    if (!providerResult.signInMethods!!.contains(credential.provider)) {
                        return@flatMap Maybe.error<AuthResult>(ProviderNotLinkedException(credential.provider))
                    } else {
                        return@flatMap RxFirebaseAuth.signInWithCredential(authInstance, credential)
                    }
                }
                .subscribe({ authResult ->
                  //Manage success
                }, { error ->
                  //Manage error
                })
  • Сначала я проверяю провайдеров, связанных с электронной почтой пользователя (вы можете получитьэто от провайдера)
  • Если в списке SignInMethods указан мой провайдер учетных данных, я выдаю ошибку, если нет, я вызываю мой signInWithCredential метод для создания пользователя.
  • Продолжите свой рабочий процесс.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...