Как связать несколько поставщиков услуг аутентификации с аккаунтом на устройстве Android

Вы можете разрешить пользователям входить в приложение, используя несколько поставщиков аутентификации, связав учетные данные поставщика с существующим аккаунтом пользователя. Пользователи идентифицируются по одному и тому же идентификатору Firebase независимо от поставщика услуг аутентификации, которого они использовали для входа в систему. Например, пользователь, вошедший в аккаунт с помощью пароля, может связать его с аккаунтом Google и в дальнейшем использовать любой из этих способов. Или анонимный пользователь может связать аккаунт Facebook, а затем войти в него, чтобы продолжить пользоваться вашим приложением.

Подготовка

Добавьте в приложение поддержку двух или более поставщиков услуг аутентификации (возможно, включая анонимную аутентификацию).

Чтобы связать учетные данные поставщика услуг аутентификации с существующим аккаунтом пользователя:

  1. Войдите в аккаунт пользователя, используя любого поставщика услуг аутентификации или любой метод.
  2. Завершите процесс входа для нового поставщика услуг аутентификации, но не вызывайте методы FirebaseAuth.signInWith. Например, получить токен идентификатора Google, токен доступа Facebook, адрес электронной почты и пароль.
  3. Получите AuthCredential для нового поставщика услуг аутентификации:

    вход с аккаунтом Google

    Kotlin

    val credential = GoogleAuthProvider.getCredential(googleIdToken, null)

    Java

    AuthCredential credential = GoogleAuthProvider.getCredential(googleIdToken, null);
    Вход через Facebook

    Kotlin

    val credential = FacebookAuthProvider.getCredential(token.token)

    Java

    AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
    Вход с помощью адреса электронной почты и пароля

    Kotlin

    val credential = EmailAuthProvider.getCredential(email, password)

    Java

    AuthCredential credential = EmailAuthProvider.getCredential(email, password);
  4. Передайте объект AuthCredential методу linkWithCredential пользователя, вошедшего в аккаунт:

    Kotlin

    auth.currentUser!!.linkWithCredential(credential)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "linkWithCredential:success")
                val user = task.result?.user
                updateUI(user)
            } else {
                Log.w(TAG, "linkWithCredential:failure", task.exception)
                Toast.makeText(
                    baseContext,
                    "Authentication failed.",
                    Toast.LENGTH_SHORT,
                ).show()
                updateUI(null)
            }
        }

    Java

    mAuth.getCurrentUser().linkWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "linkWithCredential:success");
                        FirebaseUser user = task.getResult().getUser();
                        updateUI(user);
                    } else {
                        Log.w(TAG, "linkWithCredential:failure", task.getException());
                        Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }
                }
            });

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

    Kotlin

    val prevUser = auth.currentUser
    auth.signInWithCredential(credential)
        .addOnSuccessListener { result ->
            val currentUser = result.user
            // Merge prevUser and currentUser accounts and data
            // ...
        }
        .addOnFailureListener {
            // ...
        }

    Java

    FirebaseUser prevUser = FirebaseAuth.getInstance().getCurrentUser();
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    FirebaseUser currentUser = task.getResult().getUser();
                    // Merge prevUser and currentUser accounts and data
                    // ...
                }
            });

Если вызов linkWithCredential выполнен успешно, пользователь может войти в систему, используя любого связанного поставщика аутентификации, и получить доступ к тем же данным Firebase.

С одним аккаунтом Firebase может быть связано несколько поставщиков учетных данных (например, Google, Facebook, адрес электронной почты и пароль). Это позволяет пользователю входить в один и тот же аккаунт Firebase разными способами.

Если отменить связь поставщика услуг аутентификации с аккаунтом пользователя, он больше не сможет входить в аккаунт с помощью этого поставщика.

Чтобы отменить связь поставщика аутентификации с аккаунтом пользователя, передайте идентификатор поставщика в метод unlink. Идентификаторы поставщиков услуг аутентификации, связанных с пользователем, можно получить, вызвав метод getProviderData.

Kotlin

Firebase.auth.currentUser!!.unlink(providerId)
    .addOnCompleteListener(this) { task ->
        if (task.isSuccessful) {
            // Auth provider unlinked from account
            // ...
        }
    }

Java

mAuth.getCurrentUser().unlink(providerId)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Auth provider unlinked from account
                    // ...
                }
            }
        });

Устранение неполадок

Если при попытке связать несколько аккаунтов возникают ошибки, ознакомьтесь с документацией о подтвержденных адресах электронной почты.