Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Autenticar com o Firebase usando o link de e-mail no Android

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

Você pode usar o Firebase Authentication para fazer login de um usuário enviando a ele um e-mail contendo um link, no qual ele pode clicar para fazer login. No processo, o endereço de e-mail do usuário também é verificado.

Há vários benefícios em fazer login por e-mail:

  • Inscrição e login de baixo atrito.
  • Menor risco de reutilização de senha em aplicativos, o que pode prejudicar a segurança até mesmo de senhas bem selecionadas.
  • A capacidade de autenticar um usuário e, ao mesmo tempo, verificar se o usuário é o proprietário legítimo de um endereço de e-mail.
  • Um usuário precisa apenas de uma conta de e-mail acessível para fazer login. Não é necessária a propriedade de um número de telefone ou conta de mídia social.
  • Um usuário pode fazer login com segurança sem a necessidade de fornecer (ou lembrar) uma senha, o que pode ser complicado em um dispositivo móvel.
  • Um usuário existente que fez login anteriormente com um identificador de e-mail (senha ou federado) pode ser atualizado para entrar apenas com o e-mail. Por exemplo, um usuário que esqueceu sua senha ainda pode entrar sem precisar redefinir sua senha.

Antes de você começar

Configure seu projeto Android

  1. Se ainda não o fez, adicione o Firebase ao seu projeto Android .

  2. No arquivo Gradle do módulo (nível do aplicativo) (geralmente <project>/<app-module>/build.gradle ), adicione a dependência da biblioteca Android do Firebase Authentication. Recomendamos usar o Firebase Android BoM para controlar o controle de versão da biblioteca.

    Além disso, como parte da configuração do Firebase Authentication, você precisa adicionar o SDK do Google Play Services ao seu aplicativo.

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.1.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Ao usar o Firebase Android BoM , seu aplicativo sempre usará versões compatíveis das bibliotecas do Firebase Android.

    (Alternativa) Adicionar dependências da biblioteca do Firebase sem usar o BoM

    Se você optar por não usar o Firebase BoM, deverá especificar cada versão da biblioteca do Firebase em sua linha de dependência.

    Observe que, se você usa várias bibliotecas do Firebase em seu aplicativo, é altamente recomendável usar o BoM para gerenciar as versões da biblioteca, o que garante que todas as versões sejam compatíveis.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth:21.1.0'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.1.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

    Ao usar o Firebase Android BoM , seu aplicativo sempre usará versões compatíveis das bibliotecas do Firebase Android.

    (Alternativa) Adicionar dependências da biblioteca do Firebase sem usar o BoM

    Se você optar por não usar o Firebase BoM, deverá especificar cada versão da biblioteca do Firebase em sua linha de dependência.

    Observe que, se você usa várias bibliotecas do Firebase em seu aplicativo, é altamente recomendável usar o BoM para gerenciar as versões da biblioteca, o que garante que todas as versões sejam compatíveis.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx:21.1.0'
    // Also add the dependency for the Google Play services library and specify its version implementation 'com.google.android.gms:play-services-auth:20.4.0'
    }

Para fazer login de usuários por link de e-mail, você deve primeiro ativar o provedor de e-mail e o método de login do link de e-mail para seu projeto do Firebase:

  1. No console do Firebase , abra a seção Auth .
  2. Na guia Método de login , habilite o provedor de e- mail/senha . Observe que o login por e-mail/senha deve estar habilitado para usar o login por link de e-mail.
  3. Na mesma seção, habilite o método de login do link de e-mail (entrada sem senha) .
  4. Clique em Salvar .

Para iniciar o fluxo de autenticação, apresente ao usuário uma interface que solicita que o usuário forneça seu endereço de e-mail e chame sendSignInLinkToEmail para solicitar que o Firebase envie o link de autenticação para o e-mail do usuário.

  1. Construa o objeto ActionCodeSettings , que fornece ao Firebase instruções sobre como construir o link de e-mail. Defina os seguintes campos:

    • url : O link direto a ser incorporado e qualquer estado adicional a ser transmitido. O domínio do link precisa estar na lista de permissões na lista de domínios autorizados do Firebase Console, que pode ser encontrada na guia Método de login (Autenticação -> Método de login). O link redirecionará o usuário para este URL se o aplicativo não estiver instalado em seu dispositivo e o aplicativo não puder ser instalado.
    • androidPackageName e IOSBundleId : os aplicativos a serem usados ​​quando o link de entrada é aberto em um dispositivo Android ou Apple. Saiba mais sobre como configurar o Firebase Dynamic Links para abrir links de ação de e-mail por meio de aplicativos para dispositivos móveis.
    • handleCodeInApp : Defina como true. A operação de login deve sempre ser concluída no aplicativo, ao contrário de outras ações de e-mail fora da banda (redefinição de senha e verificações de e-mail). Isso ocorre porque, no final do fluxo, espera-se que o usuário esteja conectado e seu estado de autenticação persista no aplicativo.
    • dynamicLinkDomain : quando vários domínios de link dinâmico personalizados são definidos para um projeto, especifique qual usar quando o link deve ser aberto por meio de um aplicativo móvel especificado (por exemplo, example.page.link ). Caso contrário, o primeiro domínio é selecionado automaticamente.

    Java

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    Kotlin+KTX

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        setIOSBundleId("com.example.ios")
        setAndroidPackageName(
                "com.example.android",
                true, /* installIfNotAvailable */
                "12" /* minimumVersion */)
    }

    Para saber mais sobre ActionCodeSettings, consulte a seção Passing State in Email Actions .

  2. Peça ao usuário seu e-mail.

  3. Envie o link de autenticação para o e-mail do usuário e salve o e-mail do usuário caso o usuário conclua o login de e-mail no mesmo dispositivo.

    Java

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

    Kotlin+KTX

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Email sent.")
                }
            }

Preocupações com segurança

Para evitar que um link de login seja usado para fazer login como um usuário não intencional ou em um dispositivo não intencional, o Firebase Auth exige que o endereço de e-mail do usuário seja fornecido ao concluir o fluxo de login. Para que o login seja bem-sucedido, esse endereço de e-mail deve corresponder ao endereço para o qual o link de login foi enviado originalmente.

Você pode simplificar esse fluxo para usuários que abrem o link de entrada no mesmo dispositivo em que solicitam o link, armazenando seu endereço de e-mail localmente - por exemplo, usando SharedPreferences - ao enviar o e-mail de entrada. Em seguida, use esse endereço para concluir o fluxo. Não passe o e-mail do usuário nos parâmetros de URL de redirecionamento e reutilize-o, pois isso pode permitir injeções de sessão.

Após a conclusão do login, qualquer mecanismo de login anterior não verificado será removido do usuário e todas as sessões existentes serão invalidadas. Por exemplo, se alguém criou anteriormente uma conta não verificada com o mesmo e-mail e senha, a senha do usuário será removida para impedir que o falsificador que reivindicou a propriedade e criou essa conta não verificada entre novamente com o e-mail e a senha não verificados.

Certifique-se também de usar um URL HTTPS na produção para evitar que seu link seja potencialmente interceptado por servidores intermediários.

Concluindo o login em um aplicativo Android

O Firebase Authentication usa o Firebase Dynamic Links para enviar o link de e-mail para um dispositivo móvel. Para concluir o login por meio de aplicativo móvel, o aplicativo deve ser configurado para detectar o link do aplicativo de entrada, analisar o link direto subjacente e concluir o login.

O Firebase Auth usa o Firebase Dynamic Links ao enviar um link que deve ser aberto em um aplicativo para dispositivos móveis. Para usar esse recurso, os links dinâmicos devem ser configurados no Firebase Console.

  1. Ative os links dinâmicos do Firebase:

    1. No console do Firebase , abra a seção Dynamic Links .
    2. Se você ainda não aceitou os termos do Dynamic Links e criou um domínio do Dynamic Links, faça isso agora.

      Se você já criou um domínio de links dinâmicos, anote-o. Um domínio de links dinâmicos normalmente se parece com o exemplo a seguir:

      example.page.link

      Você precisará desse valor ao configurar seu aplicativo Apple ou Android para interceptar o link de entrada.

  2. Configurando aplicativos Android:

    1. Para lidar com esses links do seu aplicativo Android, o nome do pacote Android precisa ser especificado nas configurações do projeto do Firebase Console. Além disso, o SHA-1 e o SHA-256 do certificado do aplicativo precisam ser fornecidos.
    2. Agora que você adicionou um domínio de link dinâmico e garantiu que seu aplicativo Android está configurado corretamente, o link dinâmico será redirecionado para seu aplicativo, a partir da atividade do iniciador.
    3. Se você quiser que o link dinâmico redirecione para uma atividade específica, será necessário configurar um filtro de intenção em seu arquivo AndroidManifest.xml . Isso pode ser feito especificando seu domínio de link dinâmico ou o manipulador de ação de email no filtro de intenção. Por padrão, o manipulador de ações de email é hospedado em um domínio como o exemplo a seguir:
      PROJECT_ID.firebaseapp.com/
    4. Ressalvas:
      1. Não especifique o URL que você definiu em actionCodeSettings em seu filtro de intent.
      2. Ao criar seu domínio de link dinâmico, você também pode ter criado um link de URL curto. Este URL curto não será passado; não configure seu filtro de intent para capturá-lo com um atributo android:pathPrefix . Isso significa que você não poderá capturar links dinâmicos diferentes em diferentes partes do seu aplicativo. No entanto, você pode verificar o parâmetro de consulta de mode no link para ver qual operação está tentando ser executada ou usar métodos do SDK, como isSignInWithEmailLink , para ver se um link que seu aplicativo recebeu faz o que você deseja.
    5. Para obter mais informações sobre como receber links dinâmicos, consulte as instruções de recebimento de links dinâmicos do Android .

Depois de receber o link conforme descrito acima, verifique se ele se destina à autenticação de link de e-mail e conclua o login.

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

Kotlin+KTX

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Successfully signed in with email link!")
                    val result = task.result
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error signing in with email link", task.exception)
                }
            }
}

Para saber mais sobre como lidar com o login com link de e-mail em um aplicativo da Apple, consulte o guia de plataformas da Apple .

Para saber como lidar com o login com link de e-mail em um aplicativo da Web, consulte o guia da Web .

Você também pode vincular esse método de autenticação a um usuário existente. Por exemplo, um usuário previamente autenticado com outro provedor, como um número de telefone, pode adicionar esse método de login à sua conta existente.

A diferença estaria na segunda metade da operação:

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully linked emailLink credential!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error linking emailLink credential", task.exception)
            }
        }

Isso também pode ser usado para autenticar novamente um usuário de link de e-mail antes de executar uma operação confidencial.

Java

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

Kotlin+KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // User is now successfully reauthenticated
            } else {
                Log.e(TAG, "Error reauthenticating", task.exception)
            }
        }

No entanto, como o fluxo pode terminar em um dispositivo diferente no qual o usuário original não estava conectado, esse fluxo pode não ser concluído. Nesse caso, um erro pode ser mostrado ao usuário para forçá-lo a abrir o link no mesmo dispositivo. Algum estado pode ser passado no link para fornecer informações sobre o tipo de operação e o uid do usuário.

Caso você dê suporte a login baseado em senha e link com e-mail, para diferenciar o método de login para um usuário de senha/link, use fetchSignInMethodsForEmail . Isso é útil para fluxos que priorizam o identificador em que o usuário é solicitado primeiro a fornecer seu e-mail e, em seguida, apresentado o método de login:

Java

auth.fetchSignInMethodsForEmail(email)
        .addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
            @Override
            public void onComplete(@NonNull Task<SignInMethodQueryResult> task) {
                if (task.isSuccessful()) {
                    SignInMethodQueryResult result = task.getResult();
                    List<String> signInMethods = result.getSignInMethods();
                    if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                        // User can sign in with email/password
                    } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                        // User can sign in with email/link
                    }
                } else {
                    Log.e(TAG, "Error getting sign in methods for user", task.getException());
                }
            }
        });

Kotlin+KTX

Firebase.auth.fetchSignInMethodsForEmail(email)
        .addOnSuccessListener { result ->
            val signInMethods = result.signInMethods!!
            if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                // User can sign in with email/password
            } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                // User can sign in with email/link
            }
        }
        .addOnFailureListener { exception ->
            Log.e(TAG, "Error getting sign in methods for user", exception)
        }

Conforme descrito acima, email/senha e email/link são considerados o mesmo EmailAuthProvider (mesmo PROVIDER_ID ) com diferentes métodos de login.

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()