Flutter Firebase Auth: capturando token caducado

Sep 18 2020

Estoy usando el complemento Firebase Auth para la autenticación de mi aplicación Flutter.

Hasta la actualización (no estoy seguro si es relevante) a la última versión de autenticación de Firebase:

firebase_core: ^0.5.0
firebase_auth: ^0.18.0+1

todo funcionó bien.

Ahora tengo, por primera vez, el error Sentry:

FirebaseAuthException: [firebase_auth/user-token-expired] The user's credential is no longer valid. The user must sign in again.
  File "exception.dart", line 20, in catchPlatformException
  File "zone.dart", line 1198, in _rootRunUnary
  File "zone.dart", line 1100, in _CustomZone.runUnary
  File "future_impl.dart", line 160, in _FutureListener.handleError
  File "future_impl.dart", line 708, in Future._propagateToListeners.handleError
  File "future_impl.dart", line 729, in Future._propagateToListeners
  File "future_impl.dart", line 537, in Future._completeError
  File "async_patch.dart", line 47, in _AsyncAwaitCompleter.completeError
  File "platform_channel.dart", in MethodChannel.invokeMapMethod
  File "<asynchronous suspension>"
  File "unparsed"

¿Cómo puede pasar esto? El usuario dijo que no usó esta aplicación durante unos días. Según entiendo la documentación de Firebase Authentication, el token de autenticación se actualiza automáticamente con el token de actualización.

¿Cómo puedo mitigar este problema?

¿Dónde / cómo puedo detectar esta excepción para redirigir a un usuario a la pantalla de inicio de sesión?

Respuestas

1 AnuragTripathi Sep 18 2020 at 14:47

Puedes hacer un par de cosas

Primero :

cuando un usuario inicia su aplicación, debe verificar primero si el usuario ya ha iniciado sesión o no, si lo está, luego iniciar sesión silenciosamente, si no, luego enviar al usuario a la página de inicio de sesión, a continuación se muestra un ejemplo de una aplicación I compilado hace cuatro meses (tendrá que agregar la dependencia google_sign_in a su aplicación)

class _StartingPageState extends State<StartingPage> {

  Future<dynamic> decideStartingPage() async {
    bool isUserSignedIn  = await googleSignIn.isSignedIn();

    if (isUserSignedIn == true) {
      FirebaseUser futurefbuser =await getCurrentFirebaseUser();
      assignFireBaseUser(futurefbuser);
      await googleSignIn.signInSilently();
      return HomeTabView();
    }
    else
      return LoginPage();
  }

  Future<dynamic> startingpage;

  @override
  void initState(){
    super.initState();
    startingpage=decideStartingPage();
    FirebaseAdMob.instance.initialize(appId: "ca-app-pub-...........");
  }

   @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future:startingpage,
      builder: (BuildContext ctx, AsyncSnapshot<dynamic> snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return Center( child : const CircularProgressIndicator());
        }
        else
          return snapshot.data;
      }
    );
  }
}

Segundo:

Lo segundo que puede hacer es guardar el token de acceso y (o) actualizar el token que obtiene cuando un usuario inicia sesión, cuando expire, puede obtener otro token de acceso utilizando el token de actualización. Eso significa un poco de trabajo adicional para usted, ya que tendrá que guardar el token en preferencias compartidas o en un archivo json.

Ahora, ¿dónde agregar el código que maneja el procedimiento anterior? Debe identificar lo primero que solo un usuario autenticado puede hacer, como escribir en la base de datos, es muy posible que su aplicación arroje una excepción porque el usuario no está autenticado para esa operación. Usando try, catch y finalmente puede iniciar sesión con el usuario nuevamente sin necesidad de que el usuario haga nada. para más información visite este

En el primer caso, el usuario necesitaría volver a iniciar sesión explícitamente, el segundo método requiere trabajo adicional para usted, pero es más conveniente para el usuario. La elección es tuya .