O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Autenticar usando a Apple no Android

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Você pode permitir que seus usuários se autentiquem no Firebase usando o ID Apple deles usando o SDK do Firebase para realizar o fluxo de login OAuth 2.0 de ponta a ponta.

Antes de você começar

Para fazer login de usuários usando a Apple, primeiro configure Fazer login com a Apple no site do desenvolvedor da Apple e, em seguida, ative a Apple como provedor de login para seu projeto do Firebase.

Junte-se ao Programa de Desenvolvedores da Apple

Entrar com a Apple só pode ser configurado por membros do Apple Developer Program .

Configurar login com a Apple

No site do desenvolvedor da Apple , faça o seguinte:

  1. Associe seu site ao seu aplicativo conforme descrito na primeira seção de Configurar login com a Apple para a Web . Quando solicitado, registre o seguinte URL como um URL de retorno:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Você pode obter o ID do projeto do Firebase na página de configurações do Firebase console .

    Quando terminar, anote seu novo ID de serviço, que você precisará na próxima seção.

  2. Crie um Login com a chave privada da Apple . Você precisará de sua nova chave privada e ID de chave na próxima seção.
  3. Se você usa algum dos recursos do Firebase Authentication que envia e-mails para usuários, incluindo login por link de e-mail, verificação de endereço de e-mail, revogação de alteração de conta e outros, configure o serviço de retransmissão de e-mail privado da Apple e registre noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (ou seu domínio de modelo de e-mail personalizado) para que a Apple possa retransmitir e-mails enviados pelo Firebase Authentication para endereços de e-mail anônimos da Apple.

Ativar a Apple como provedor de login

  1. Adicione o Firebase ao seu projeto Android . Certifique-se de registrar a assinatura SHA-1 do seu aplicativo ao configurá-lo no Firebase console.
  2. No console do Firebase , abra a seção Auth . Na guia Método de login , habilite o provedor Apple . Especifique o ID do serviço que você criou na seção anterior. Além disso, na seção de configuração do fluxo de código OAuth , especifique seu ID de equipe da Apple e a chave privada e o ID da chave que você criou na seção anterior.

Cumpra os requisitos de dados anônimos da Apple

Entrar com a Apple oferece aos usuários a opção de anonimizar seus dados, incluindo seu endereço de e-mail, ao fazer login. Os usuários que escolhem essa opção têm endereços de e-mail com o domínio privaterelay.appleid.com . Ao usar o Login com a Apple em seu aplicativo, você deve cumprir todas as políticas ou termos de desenvolvedor aplicáveis ​​da Apple em relação a esses IDs Apple anônimos.

Isso inclui a obtenção de qualquer consentimento necessário do usuário antes de associar qualquer informação pessoal de identificação direta a um ID Apple anônimo. Ao usar o Firebase Authentication, isso pode incluir as seguintes ações:

  • Vincule um endereço de e-mail a um ID Apple anônimo ou vice-versa.
  • Vincular um número de telefone a um ID Apple anônimo ou vice-versa
  • Vincule uma credencial social não anônima (Facebook, Google, etc) a um ID Apple anônimo ou vice-versa.

A lista acima não é exaustiva. Consulte o Contrato de Licença do Apple Developer Program na seção Membership da sua conta de desenvolvedor para garantir que seu aplicativo atenda aos requisitos da Apple.

Gerencie o fluxo de login com o SDK do Firebase

No Android, a maneira mais fácil de autenticar seus usuários com o Firebase usando suas contas da Apple é lidar com todo o fluxo de login com o Firebase Android SDK.

Para lidar com o fluxo de login com o Firebase Android SDK, siga estas etapas:

  1. Construa uma instância de um OAuthProvider usando seu Builder com o ID do provedor apple.com :

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    
  2. Opcional: especifique escopos adicionais do OAuth 2.0 além do padrão que você deseja solicitar ao provedor de autenticação.

    Java

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("email");
            add("name");
          }
        };
    provider.setScopes(scopes);
    

    Kotlin+KTX

    provider.setScopes(arrayOf("email", "name"))
    

    Por padrão, quando uma conta por endereço de e-mail está ativada, o Firebase solicita escopos de e-mail e nome. Se você alterar essa configuração para Várias contas por endereço de e-mail , o Firebase não solicitará escopos da Apple, a menos que você os especifique.

  3. Opcional: se você quiser exibir a tela de login da Apple em um idioma diferente do inglês, defina o parâmetro locale . Consulte os documentos Entrar com a Apple para obter as localidades com suporte.

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    
  4. Autentique-se com o Firebase usando o objeto do provedor OAuth. Observe que, diferentemente de outras operações do FirebaseAuth , isso assumirá o controle da sua interface do usuário abrindo uma guia personalizada do Chrome. Consequentemente, não faça referência à sua atividade no OnSuccessListener e OnFailureListener que você anexar, pois eles serão desconectados imediatamente quando a operação iniciar a interface do usuário.

    Você deve primeiro verificar se já recebeu uma resposta. Fazer login com esse método coloca sua atividade em segundo plano, o que significa que ela pode ser recuperada pelo sistema durante o fluxo de login. Para garantir que você não faça o usuário tentar novamente se isso acontecer, você deve verificar se um resultado já está presente.

    Para verificar se há um resultado pendente, chame getPendingAuthResult() :

    Java

    mAuth = FirebaseAuth.getInstance();
    Task<AuthResult> pending = mAuth.getPendingAuthResult();
    if (pending != null) {
        pending.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                Log.d(TAG, "checkPending:onSuccess:" + authResult);
                // Get the user profile with authResult.getUser() and
                // authResult.getAdditionalUserInfo(), and the ID
                // token from Apple with authResult.getCredential().
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "checkPending:onFailure", e);
            }
        });
    } else {
        Log.d(TAG, "pending: null");
    }
    

    Kotlin+KTX

    val pending = auth.pendingAuthResult
    if (pending != null) {
        pending.addOnSuccessListener { authResult ->
            Log.d(TAG, "checkPending:onSuccess:$authResult")
            // Get the user profile with authResult.getUser() and
            // authResult.getAdditionalUserInfo(), and the ID
            // token from Apple with authResult.getCredential().
        }.addOnFailureListener { e ->
            Log.w(TAG, "checkPending:onFailure", e)
        }
    } else {
        Log.d(TAG, "pending: null")
    }
    

    Se não houver resultado pendente, inicie o fluxo de login, chamando startActivityForSignInWithProvider() :

    Java

    mAuth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Sign-in successful!
                            Log.d(TAG, "activitySignIn:onSuccess:" + authResult.getUser());
                            FirebaseUser user = authResult.getUser();
                            // ...
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "activitySignIn:onFailure", e);
                        }
                    });
    

    Kotlin+KTX

    auth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener { authResult ->
                // Sign-in successful!
                Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                val user = authResult.user
                // ...
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "activitySignIn:onFailure", e)
            }
    

    Ao contrário de outros provedores compatíveis com o Firebase Auth, a Apple não fornece um URL de foto.

    Além disso, quando o usuário opta por não compartilhar seu e-mail com o aplicativo, a Apple fornece um endereço de e-mail exclusivo para esse usuário (no formato xyz@privaterelay.appleid.com ), que é compartilhado com seu aplicativo. Se você configurou o serviço de retransmissão de e-mail privado, a Apple encaminha os e-mails enviados para o endereço anônimo para o endereço de e-mail real do usuário.

    A Apple só compartilha informações do usuário, como o nome de exibição, com aplicativos na primeira vez que um usuário faz login. Normalmente, o Firebase armazena o nome de exibição na primeira vez que um usuário faz login com a Apple, que você pode obter com getCurrentUser().getDisplayName() . No entanto, se você usou a Apple anteriormente para fazer login de um usuário no aplicativo sem usar o Firebase, a Apple não fornecerá ao Firebase o nome de exibição do usuário.

Reautenticação e vinculação de contas

O mesmo padrão pode ser usado com startActivityForReauthenticateWithProvider() que você pode usar para recuperar uma nova credencial para operações confidenciais que exigem login recente:

Java

// The user is already signed-in.
FirebaseUser firebaseUser = mAuth.getCurrentUser();

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener(
        new OnSuccessListener<AuthResult>() {
          @Override
          public void onSuccess(AuthResult authResult) {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
          }
        })
    .addOnFailureListener(
        new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Handle failure.
          }
        });

Kotlin+KTX

// The user is already signed-in.
val firebaseUser = auth.getCurrentUser()

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener( authResult -> {
        // User is re-authenticated with fresh tokens and
        // should be able to perform sensitive operations
        // like account deletion and email or password
        // update.
    })
    .addOnFailureListener( e -> {
        // Handle failure.
    })

E você pode usar linkWithCredential() para vincular diferentes provedores de identidade a contas existentes.

Observe que a Apple exige que você obtenha o consentimento explícito dos usuários antes de vincular suas contas da Apple a outros dados.

Por exemplo, para vincular uma conta do Facebook à conta atual do Firebase, use o token de acesso obtido ao fazer login do usuário no Facebook:

Java

// Initialize a Facebook credential with a Facebook access token.
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      }
    });

Kotlin+KTX

// Initialize a Facebook credential with a Facebook access token.
val credential = FacebookAuthProvider.getCredential(token.getToken())

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, task -> {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      });

Avançado: lidar com o fluxo de login manualmente

Você também pode se autenticar com o Firebase usando uma conta da Apple manipulando o fluxo de login usando o Apple Sign-In JS SDK, criando manualmente o fluxo OAuth ou usando uma biblioteca OAuth, como AppAuth .

  1. Para cada solicitação de login, gere uma string aleatória — um "nonce" — que você usará para garantir que o token de ID recebido foi concedido especificamente em resposta à solicitação de autenticação do seu aplicativo. Esta etapa é importante para evitar ataques de repetição.

    Você pode gerar um nonce criptograficamente seguro no Android com SecureRandom , como no exemplo a seguir:

    Java

    private String generateNonce(int length) {
        SecureRandom generator = new SecureRandom();
    
        CharsetDecoder charsetDecoder = StandardCharsets.US_ASCII.newDecoder();
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE);
    
        byte[] bytes = new byte[length];
        ByteBuffer inBuffer = ByteBuffer.wrap(bytes);
        CharBuffer outBuffer = CharBuffer.allocate(length);
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes);
            inBuffer.rewind();
            charsetDecoder.reset();
            charsetDecoder.decode(inBuffer, outBuffer, false);
        }
        outBuffer.flip();
        return outBuffer.toString();
    }
    

    Kotlin+KTX

    private fun generateNonce(length: Int): String {
        val generator = SecureRandom()
    
        val charsetDecoder = StandardCharsets.US_ASCII.newDecoder()
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE)
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE)
    
        val bytes = ByteArray(length)
        val inBuffer = ByteBuffer.wrap(bytes)
        val outBuffer = CharBuffer.allocate(length)
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes)
            inBuffer.rewind()
            charsetDecoder.reset()
            charsetDecoder.decode(inBuffer, outBuffer, false)
        }
        outBuffer.flip()
        return outBuffer.toString()
    }
    

    Em seguida, obtenha o hash SHA246 do nonce como uma string hexadecimal:

    Java

    private String sha256(String s) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(s.getBytes());
        StringBuilder hash = new StringBuilder();
        for (byte c: digest) {
            hash.append(String.format("%02x", c));
        }
        return hash.toString();
    }
    

    Kotlin+KTX

    private fun sha256(s: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val digest = md.digest(s.toByteArray())
        val hash = StringBuilder()
        for (c in digest) {
            hash.append(String.format("%02x", c))
        }
        return hash.toString()
    }
    

    Você enviará o hash SHA256 do nonce com sua solicitação de entrada, que a Apple passará inalterada na resposta. O Firebase valida a resposta fazendo hash do nonce original e comparando-o com o valor passado pela Apple.

  2. Inicie o fluxo de entrada da Apple usando sua biblioteca OAuth ou outro método. Certifique-se de incluir o nonce com hash como um parâmetro em sua solicitação.

  3. Depois de receber a resposta da Apple, obtenha o token de ID da resposta e use-o e o nonce sem hash para criar um AuthCredential :

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    

    Kotlin+KTX

    val credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build()
    
  4. Autentique-se com o Firebase usando a credencial do Firebase:

    Java

    mAuth.signInWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
          @Override
          public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
              // User successfully signed in with Apple ID token.
              // ...
            }
          }
        });
    

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { task ->
              if (task.isSuccessful) {
                // User successfully signed in with Apple ID token.
                // ...
              }
          }
    

Se a chamada para signInWithCredential for bem-sucedida, você poderá usar o método getCurrentUser para obter os dados da conta do usuário.

Próximos passos

Depois que um usuário entra pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, ou seja, o nome de usuário e a senha, o número de telefone ou as informações do provedor de autenticação com as quais o usuário fez login. Essa nova conta é armazenada como parte do seu projeto do Firebase e pode ser usada para identificar um usuário em todos os aplicativos do projeto, independentemente de como o usuário faça login.

  • Nos seus aplicativos, você pode obter as informações básicas do perfil do usuário no objeto FirebaseUser . Consulte Gerenciar usuários .

  • Nas regras de segurança do Firebase Realtime Database e do Cloud Storage , você pode obter o ID de usuário exclusivo do usuário conectado a partir da variável de auth e usá-lo para controlar quais dados um usuário pode acessar.

Você pode permitir que os usuários façam login no seu aplicativo usando vários provedores de autenticação vinculando as credenciais do provedor de autenticação a uma conta de usuário existente.

Para desconectar um usuário, chame signOut :

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()