Autenticación telefónica

La autenticación telefónica permite que los usuarios accedan a Firebase con su teléfono como autenticador. El usuario recibe un mensaje SMS (al número de teléfono proporcionado) que contiene un código único. Una vez que se autoriza el código, el usuario puede acceder a Firebase.

Los números de teléfono que proporcionen los usuarios finales para la autenticación se enviarán a Google y se almacenarán para mejorar la prevención del abuso y el spam en los servicios de Google, incluido Firebase. Los desarrolladores deben asegurarse de contar con el consentimiento correspondiente del usuario final antes de usar el servicio de autenticación con número de teléfono de Firebase Authentication.

La autenticación telefónica de Firebase no está disponible en todos los países. Consulta las Preguntas frecuentes para obtener más información.

Configuración

Antes de comenzar a usar la autenticación telefónica, asegúrate de haber seguido estos pasos:

  1. Habilita el teléfono como método de acceso en Firebase console.
  2. Android: Si aún no has configurado el hash SHA-1 de tu app, hazlo en Firebase console. Consulta Autentica tu cliente para obtener información sobre cómo encontrar el hash SHA-1 de tu app.
  3. iOS: En Xcode, habilita las notificaciones push para el proyecto y asegúrate de que la clave de autenticación de APNS esté configurada con Firebase Cloud Messaging (FCM). Además, debes habilitar los modos en segundo plano para las notificaciones remotas. Si quieres obtener una explicación detallada de este paso, consulta la documentación de Autenticación telefónica de iOS para Firebase.
  4. Web: Asegúrate de haber agregado el dominio de tus aplicaciones en Firebase console, en Dominios de redireccionamiento de OAuth.

Nota: El acceso con número de teléfono solo se puede usar en dispositivos reales y la Web. Para probar el flujo de autenticación en emuladores de dispositivos, consulta Pruebas.

Uso

El SDK de Firebase Authentication para Flutter ofrece dos maneras individuales para que el usuario acceda con su número de teléfono. Las plataformas nativas (p. ej., iOS y Android) proporcionan una funcionalidad diferente para validar un número de teléfono que la Web, por lo que existen dos métodos para cada plataforma exclusivamente:

  • Plataforma nativa: verifyPhoneNumber.
  • Plataforma web: signInWithPhoneNumber.

Nativo: verifyPhoneNumber

En las plataformas nativas, primero se debe verificar el número de teléfono del usuario y, luego, este puede acceder o vincular su cuenta con una PhoneAuthCredential.

Primero debes solicitarle al usuario su número de teléfono. Luego de que lo proporcione, llama al método verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Hay 4 devoluciones de llamada separadas que debes controlar, cada una determinará la forma en la que actualices la IU de la aplicación:

  1. verificationCompleted: Manejo automático del código SMS en dispositivos Android
  2. verificationFailed: Manejo de eventos de falla, como los números de teléfono no válidos, o si se superó la cuota de SMS
  3. codeSent: Control del momento en que se envía un código al dispositivo desde Firebase, y se usa para solicitar a los usuarios que ingresen el código
  4. codeAutoRetrievalTimeout: Control de un tiempo de espera cuando falla el manejo automático de código por SMS

verificationCompleted

Solo se llamará a este controlador en dispositivos Android que admitan la resolución automática de código SMS.

Cuando se entregue el código de SMS al dispositivo, Android lo verificará automáticamente sin que el usuario tenga que ingresarlo de forma manual. Si este evento ocurre, se proporciona automáticamente una PhoneAuthCredential que se puede usar para acceder con el número de teléfono del usuario o vincularlo.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

Si Firebase muestra un error, por ejemplo, para un número de teléfono incorrecto o si se excedió la cuota de SMS para el proyecto, se enviará una FirebaseAuthException a este controlador. En este caso, le pedirás al usuario que se produjo un error según el código de error.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

Cuando Firebase envía un código de SMS al dispositivo, este controlador se activa con un verificationId y resendToken (un resendToken solo se admite en dispositivos Android, los dispositivos iOSsiempre mostrarán un valor null).

Una vez activado, será un buen momento para actualizar la IU de tu aplicación a fin de solicitarle al usuario que ingrese el código de SMS que espera. Una vez que hayas ingresado el código SMS, podrás combinar el ID de verificación con el código SMS para crear una PhoneAuthCredential nueva:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

De forma predeterminada, Firebase no volverá a enviar mensajes SMS nuevos si se enviaron recientemente. Sin embargo, puedes anular este comportamiento si vuelves a llamar al método verifyPhoneNumber con el token de reenvío al argumento forceResendingToken. Si se hace correctamente, se volverá a enviar el SMS.

codeAutoRetrievalTimeout

En dispositivos Android que admiten la resolución automática de código SMS, se llamará a este controlador si el dispositivo no resolvió automáticamente un mensaje SMS en un plazo determinado. Una vez transcurrido el plazo, el dispositivo ya no intentará resolver los mensajes entrantes.

De forma predeterminada, el dispositivo espera 30 segundos, pero esto se puede personalizar con el argumento timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Web: signInWithPhoneNumber

Para acceder a las plataformas web, los usuarios deben confirmar que tienen acceso a un teléfono mediante el ingreso del código SMS enviado al número de teléfono proporcionado. Para aumentar la seguridad y prevenir el spam, se solicitará a los usuarios que completen el widget de Google reCAPTCHA a fin de comprobar que son humanos. Una vez confirmado, se enviará el código SMS.

El SDK de Firebase Authentication para Flutter administrará el widget de reCAPTCHA de forma predeterminada. Sin embargo, proporcionará control sobre cómo se muestra y configura si es necesario. Para comenzar, llama al método signInWithPhoneNumber con el número de teléfono.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

Una llamada al método primero activará el widget de reCAPTCHA. El usuario debe completar la prueba antes de que se envíe un código por SMS. Cuando hayas terminado, podrás permitir que el usuario acceda proporcionando el código de SMS al método confirm en la respuesta resuelta de ConfirmationResult:

UserCredential userCredential = await confirmationResult.confirm('123456');

Al igual que otros flujos de acceso, un acceso exitoso activará todos los objetos de escucha de estado de autenticación que hayas suscrito en tu aplicación.

Configuración de reCAPTCHA

El widget de reCAPTCHA es un flujo completamente administrado que proporciona seguridad a tu aplicación web.

El segundo argumento de signInWithPhoneNumber acepta una instancia de RecaptchaVerifier opcional que se puede usar para administrar el widget. De forma predeterminada, el widget se renderizará como invisible cuando se active el flujo de acceso. Un widget “invisible” aparecerá como una ventana modal de página completa en la parte superior de tu aplicación.

Sin embargo, es posible mostrar un widget intercalado que el usuario debe presionar de manera explícita para verificarse.

Para agregar un widget intercalado, especifica un ID de elemento DOM al argumento container de la instancia de RecaptchaVerifier. El elemento debe existir y estar vacío, de lo contrario, aparecerá un error. Si no se proporciona un argumento container, el widget se renderizará como “invisible”.

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

De manera opcional, puedes cambiar el tamaño y el tema si personalizas los argumentos size y theme como se mostró anteriormente.

También es posible detectar eventos, por ejemplo, si el usuario completó el reCAPTCHA, si este venció o se produjo un error:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Prueba

Firebase ofrece compatibilidad con los números de teléfono de prueba local:

  1. En Firebase console, selecciona el proveedor de autenticación de “Teléfono” y haz clic en el menú desplegable “Números de teléfono para las pruebas”.
  2. Ingresa un número de teléfono nuevo (p. ej., +44 7444 555666) y un código de prueba (p. ej., 123456).

Si proporcionas un número de teléfono de prueba a los métodos verifyPhoneNumber o signInWithPhoneNumber, no se enviará ningún SMS. En su lugar, puedes proporcionar el código de prueba directamente al PhoneAuthProvider o con el controlador de resultados de confirmación de signInWithPhoneNumber.