Criar gerenciadores de ações de e-mail personalizados

Algumas ações de gerenciamento de usuários, como atualizar o endereço de e-mail e redefinir a senha, resultam no envio de e-mails para ele. Esses e-mails contêm links que os destinatários podem abrir para concluir ou cancelar a ação de gerenciamento de usuários. Por padrão, os e-mails de gerenciamento de usuários são vinculados a um gerenciador de ação padrão, que é uma página da Web hospedada em um URL no domínio do Firebase Hosting do seu projeto.

Em vez disso, você pode criar e hospedar um gerenciador personalizado de ações de e-mail para personalizar o processamento e integrar o gerenciador ao seu site.

As seguintes ações de gerenciamento de usuários exigem que o usuário utilize um gerenciador de ações de e-mail:

  • Redefinição de senhas
  • Revogação de alterações de endereço de e-mail: quando os usuários mudam o endereço de e-mail primário da conta, uma mensagem é enviada pelo Firebase ao antigo endereço para que os usuários possam desfazer a alteração.
  • Verificação de endereços de e-mail

Para personalizar o gerenciador de ações de e-mail do seu projeto do Firebase, crie e hospede uma página da Web que use o SDK do Firebase para JavaScript para verificar a validade da solicitação e concluí-la. Em seguida, personalize os modelos de e-mail do seu projeto do Firebase e vincule-os ao seu gerenciador de ações personalizado.

Criar a página do gerenciador de ações de e-mail

  1. Vários parâmetros de consulta são adicionados ao URL do gerenciador de ações quando e-mails de gerenciamento de usuários são gerados pelo Firebase. Por exemplo:

    https://example.com/usermgmt?mode=resetPassword&oobCode=ABC123&apiKey=AIzaSy...&lang=fr

    Esses parâmetros especificam a tarefa de gerenciamento de usuários que está sendo realizada. Sua página do gerenciador de ações de e-mail precisa resolver os seguintes parâmetros de consulta:

    Parâmetros
    mode

    A ação de gerenciamento de usuários a ser concluída. Pode ser um dos seguintes valores:

    • resetPassword
    • recoverEmail
    • verifyEmail
    oobCode Um código único utilizado para identificar e verificar uma solicitação.
    apiKey A chave de API do seu projeto do Firebase, fornecida para fins de praticidade.
    continueUrl Esse é um URL opcional que fornece uma maneira de transmitir o estado de volta ao app por um URL. Isso é relevante para os modos de redefinição de senha e verificação de e-mail. Ao enviar um e-mail de redefinição de senha ou um e-mail de verificação, um objeto ActionCodeSettings precisa ser especificado com um URL de confirmação para que ele esteja disponível. Isso permite que um usuário continue de onde parou depois de uma ação de e-mail.
    lang

    Esta é a tag de idioma BCP47 opcional que representa a localidade do usuário (por exemplo, fr). Use esse valor para fornecer páginas localizadas do gerenciador de ações de e-mail para seus usuários.

    A localização pode ser definida por meio do Console do Firebase ou dinamicamente. Para isso, chame a API do cliente correspondente antes de acionar a ação de e-mail. Por exemplo, usando JavaScript: firebase.auth().languageCode = 'fr';.

    Para uma experiência de usuário consistente, verifique se a localização do gerenciador de ações de e-mail corresponde àquela dos modelos de e-mail.

    O exemplo a seguir mostra como processar os parâmetros de consulta em um gerenciador baseado em navegador. Você também pode implementar o gerenciador como um aplicativo Node.js usando uma lógica semelhante.

    API modular da Web

    import { initializeApp } from "firebase/app";
    import { getAuth } from "firebase/auth";
    
    document.addEventListener('DOMContentLoaded', () => {
      // TODO: Implement getParameterByName()
    
      // Get the action to complete.
      const mode = getParameterByName('mode');
      // Get the one-time code from the query parameter.
      const actionCode = getParameterByName('oobCode');
      // (Optional) Get the continue URL from the query parameter if available.
      const continueUrl = getParameterByName('continueUrl');
      // (Optional) Get the language code if available.
      const lang = getParameterByName('lang') || 'en';
    
      // Configure the Firebase SDK.
      // This is the minimum configuration required for the API to be used.
      const config = {
        'apiKey': "YOU_API_KEY" // Copy this key from the web initialization
                                // snippet found in the Firebase console.
      };
      const app = initializeApp(config);
      const auth = getAuth(app);
    
      // Handle the user management action.
      switch (mode) {
        case 'resetPassword':
          // Display reset password handler and UI.
          handleResetPassword(auth, actionCode, continueUrl, lang);
          break;
        case 'recoverEmail':
          // Display email recovery handler and UI.
          handleRecoverEmail(auth, actionCode, lang);
          break;
        case 'verifyEmail':
          // Display email verification handler and UI.
          handleVerifyEmail(auth, actionCode, continueUrl, lang);
          break;
        default:
          // Error: invalid mode.
      }
    }, false);

    API com namespace da Web

    document.addEventListener('DOMContentLoaded', () => {
      // TODO: Implement getParameterByName()
    
      // Get the action to complete.
      var mode = getParameterByName('mode');
      // Get the one-time code from the query parameter.
      var actionCode = getParameterByName('oobCode');
      // (Optional) Get the continue URL from the query parameter if available.
      var continueUrl = getParameterByName('continueUrl');
      // (Optional) Get the language code if available.
      var lang = getParameterByName('lang') || 'en';
    
      // Configure the Firebase SDK.
      // This is the minimum configuration required for the API to be used.
      var config = {
        'apiKey': "YOU_API_KEY" // Copy this key from the web initialization
                                // snippet found in the Firebase console.
      };
      var app = firebase.initializeApp(config);
      var auth = app.auth();
    
      // Handle the user management action.
      switch (mode) {
        case 'resetPassword':
          // Display reset password handler and UI.
          handleResetPassword(auth, actionCode, continueUrl, lang);
          break;
        case 'recoverEmail':
          // Display email recovery handler and UI.
          handleRecoverEmail(auth, actionCode, lang);
          break;
        case 'verifyEmail':
          // Display email verification handler and UI.
          handleVerifyEmail(auth, actionCode, continueUrl, lang);
          break;
        default:
          // Error: invalid mode.
      }
    }, false);
  2. Gerencie as solicitações de redefinição de senha verificando primeiro o código de ação com verifyPasswordResetCode. Em seguida, receba uma nova senha do usuário e transmita-a para confirmPasswordReset. Exemplo:

    API modular da Web

    import { verifyPasswordResetCode, confirmPasswordReset } from "firebase/auth";
    
    function handleResetPassword(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
    
      // Verify the password reset code is valid.
      verifyPasswordResetCode(auth, actionCode).then((email) => {
        const accountEmail = email;
    
        // TODO: Show the reset screen with the user's email and ask the user for
        // the new password.
        const newPassword = "...";
    
        // Save the new password.
        confirmPasswordReset(auth, actionCode, newPassword).then((resp) => {
          // Password reset has been confirmed and new password updated.
    
          // TODO: Display a link back to the app, or sign-in the user directly
          // if the page belongs to the same domain as the app:
          // auth.signInWithEmailAndPassword(accountEmail, newPassword);
    
          // TODO: If a continue URL is available, display a button which on
          // click redirects the user back to the app via continueUrl with
          // additional state determined from that URL's parameters.
        }).catch((error) => {
          // Error occurred during confirmation. The code might have expired or the
          // password is too weak.
        });
      }).catch((error) => {
        // Invalid or expired action code. Ask user to try to reset the password
        // again.
      });
    }

    API com namespace da Web

    function handleResetPassword(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
    
      // Verify the password reset code is valid.
      auth.verifyPasswordResetCode(actionCode).then((email) => {
        var accountEmail = email;
    
        // TODO: Show the reset screen with the user's email and ask the user for
        // the new password.
        var newPassword = "...";
    
        // Save the new password.
        auth.confirmPasswordReset(actionCode, newPassword).then((resp) => {
          // Password reset has been confirmed and new password updated.
    
          // TODO: Display a link back to the app, or sign-in the user directly
          // if the page belongs to the same domain as the app:
          // auth.signInWithEmailAndPassword(accountEmail, newPassword);
    
          // TODO: If a continue URL is available, display a button which on
          // click redirects the user back to the app via continueUrl with
          // additional state determined from that URL's parameters.
        }).catch((error) => {
          // Error occurred during confirmation. The code might have expired or the
          // password is too weak.
        });
      }).catch((error) => {
        // Invalid or expired action code. Ask user to try to reset the password
        // again.
      });
    }
  3. Gerencie as revogações de alteração de endereço de e-mail verificando primeiro o código de ação com checkActionCode. Em seguida, restaure o endereço de e-mail do usuário com applyActionCode. Exemplo:

    API modular da Web

    import { checkActionCode, applyActionCode, sendPasswordResetEmail } from "firebase/auth";
    
    function handleRecoverEmail(auth, actionCode, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      let restoredEmail = null;
      // Confirm the action code is valid.
      checkActionCode(auth, actionCode).then((info) => {
        // Get the restored email address.
        restoredEmail = info['data']['email'];
    
        // Revert to the old email.
        return applyActionCode(auth, actionCode);
      }).then(() => {
        // Account email reverted to restoredEmail
    
        // TODO: Display a confirmation message to the user.
    
        // You might also want to give the user the option to reset their password
        // in case the account was compromised:
        sendPasswordResetEmail(auth, restoredEmail).then(() => {
          // Password reset confirmation sent. Ask user to check their email.
        }).catch((error) => {
          // Error encountered while sending password reset code.
        });
      }).catch((error) => {
        // Invalid code.
      });
    }

    API com namespace da Web

    function handleRecoverEmail(auth, actionCode, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      var restoredEmail = null;
      // Confirm the action code is valid.
      auth.checkActionCode(actionCode).then((info) => {
        // Get the restored email address.
        restoredEmail = info['data']['email'];
    
        // Revert to the old email.
        return auth.applyActionCode(actionCode);
      }).then(() => {
        // Account email reverted to restoredEmail
    
        // TODO: Display a confirmation message to the user.
    
        // You might also want to give the user the option to reset their password
        // in case the account was compromised:
        auth.sendPasswordResetEmail(restoredEmail).then(() => {
          // Password reset confirmation sent. Ask user to check their email.
        }).catch((error) => {
          // Error encountered while sending password reset code.
        });
      }).catch((error) => {
        // Invalid code.
      });
    }
  4. Para gerenciar a verificação de endereço de e-mail, chame applyActionCode. Exemplo:

    API modular da Web

    function handleVerifyEmail(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      // Try to apply the email verification code.
      applyActionCode(auth, actionCode).then((resp) => {
        // Email address has been verified.
    
        // TODO: Display a confirmation message to the user.
        // You could also provide the user with a link back to the app.
    
        // TODO: If a continue URL is available, display a button which on
        // click redirects the user back to the app via continueUrl with
        // additional state determined from that URL's parameters.
      }).catch((error) => {
        // Code is invalid or expired. Ask the user to verify their email address
        // again.
      });
    }

    API com namespace da Web

    function handleVerifyEmail(auth, actionCode, continueUrl, lang) {
      // Localize the UI to the selected language as determined by the lang
      // parameter.
      // Try to apply the email verification code.
      auth.applyActionCode(actionCode).then((resp) => {
        // Email address has been verified.
    
        // TODO: Display a confirmation message to the user.
        // You could also provide the user with a link back to the app.
    
        // TODO: If a continue URL is available, display a button which on
        // click redirects the user back to the app via continueUrl with
        // additional state determined from that URL's parameters.
      }).catch((error) => {
        // Code is invalid or expired. Ask the user to verify their email address
        // again.
      });
    }
  5. Hospede a página em algum lugar, por exemplo, usando o Firebase Hosting.

Em seguida, vincule seu gerenciador personalizado de ações de e-mail ao seu projeto do Firebase nos e-mails de gerenciamento de usuários.

Para configurar seu projeto do Firebase de forma que ele use um gerenciador personalizado de ações de e-mail:

  1. Abra seu projeto no Console do Firebase.
  2. Vá para a página Modelos de e-mail na seção Auth.
  3. Em qualquer uma das entradas Tipos de e-mail, clique no ícone de lápis para editar o modelo de e-mail.
  4. Clique em Personalizar URL acionável e especifique o URL do gerenciador personalizado de ações de e-mail.

Depois de salvar o URL, ele será usado por todos os modelos de e-mail do projeto do Firebase.