Cómo eliminar un usuario en Firebase con Flutter


Avatar de Pedro Cortez

Permitir que un usuario elimine su cuenta es una funcionalidad obligatoria para publicar tu aplicación en Android o Apple. Aquí te explico las dos maneras de realizar esta acción, para asegurarte de que tu aplicación Flutter cumpla con los requisitos.


Eliminación manual de un usuario desde la consola Firebase

La forma más sencilla y directa de eliminar una cuenta en Firebase es hacerlo manualmente desde la consola. Para eliminar un usuario de tu aplicación Flutter, sigue estos pasos:

  1. Acceder a la consola de Firebase: Inicia sesión en la consola Firebase y selecciona tu proyecto.
  2. Ir a la sección de autenticación: En el menú de la izquierda, selecciona «Autenticación» para acceder a la lista de usuarios de tu aplicación.
  3. Eliminar un usuario: En la pestaña «Usuarios», verás una lista de todos los usuarios registrados. Puedes buscar al usuario que deseas eliminar por su correo electrónico o su identificador de usuario. Luego, haz clic en los tres puntos a la derecha del usuario y selecciona «Eliminar».

La eliminación de un usuario desde Firebase Authentication no elimina sus datos en Firestore o Realtime Database. Si tienes información adicional almacenada, recuerda eliminarla manualmente.

Eliminación de un usuario desde una aplicación Flutter

Si bien eliminar un usuario manualmente es posible, no es la mejor solución desde el punto de vista de la experiencia del usuario (UX) y la escalabilidad. Aquí te comparto un código que puedes adaptar según tus necesidades, para que un usuario pueda eliminar su cuenta directamente desde tu aplicación Flutter.

El funcionamiento sigue estas etapas:

  1. Una vez confirmado, se elimina la cuenta del usuario tanto de Firebase Authentication como de Firestore.
  2. Aparece un mensaje cuando el usuario toca brevemente el botón, pidiéndole que lo mantenga presionado si realmente desea eliminar su cuenta.
  3. Si el usuario mantiene presionado el botón, aparece un cuadro de diálogo para confirmar la acción.
// Declaración de una instancia de FirebaseAuth 
FirebaseAuth auth = FirebaseAuth.instance;

// Botón para eliminar la cuenta
ElevatedButton(
  onPressed: () {
    Fluttertoast.showToast(
      msg: "Mantén presionado para eliminar tu cuenta. Esta acción es definitiva.",
    );
  },
  onLongPress: () async {
    _showDeleteConfirmation(context);
  },
  child: const Text("Eliminar mi cuenta"),
),

//Función para mostrar la confirmación de eliminación
void _showDeleteConfirmation(BuildContext context) {
  showDialog(
    context: context,
    builder: (BuildContext dialogContext) {
      return AlertDialog(
        title: const Text("Confirmar eliminación"),
        content: const Text(
          "¿Estás seguro de que deseas eliminar tu cuenta? Esta acción es definitiva.",
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(dialogContext),
            child: const Text("Cancelar"),
          ),
          TextButton(
            onPressed: () async {
              // Cerrar el cuadro de diálogo
              Navigator.pop(dialogContext);

              // Eliminar la cuenta del usuario
              var userID = FirebaseAuth.instance.currentUser!.uid;

              try {
                await _deleteUserInfo(userID); // Eliminar datos de Firestore
                await deleteUserAccount(); // Eliminar cuenta de Firebase
              } catch (e) {
                print("Error al eliminar la cuenta: $e");
              }

              // Redirección tras la eliminación
              Navigator.pushReplacement(
                dialogContext,
                MaterialPageRoute(builder: (_) => const FirstScreen()),
              );
            },
            child: const Text(
              "Eliminar",
              style: TextStyle(color: Colors.red),
            ),
          ),
        ],
      );
    },
  );
}


//Future<void> deleteUserAccount() async {
  try {
    await FirebaseAuth.instance.currentUser!.delete();
  } on FirebaseAuthException catch (e) {
    if (e.code == "requires-recent-login") {
      await _reauthenticateAndDelete();
    } else {
      print("Error de Firebase: $e");
    }
  } catch (e) {
    print("Error al eliminar la cuenta: $e");
  }
}


//Función para reautenticar al usuario si es necesario antes de eliminarlo
Future<void> _reauthenticateAndDelete() async {
  try {
    final providerData = auth.currentUser?.providerData.first;

    if (AppleAuthProvider().providerId == providerData!.providerId) {
      await auth.currentUser!.reauthenticateWithProvider(AppleAuthProvider());
    } else if (GoogleAuthProvider().providerId == providerData.providerId) {
      await auth.currentUser!.reauthenticateWithProvider(GoogleAuthProvider());
    }

    await auth.currentUser?.delete();
  } catch (e) {
    print("Error al reautenticar: $e");
  }
}

//Función para eliminar los datos del usuario en Firestore
//Recuerda reemplazar el nombre de la colección y las rutas según las que uses en tu aplicación.
Future<void> _deleteUserInfo(String userID) async {
  try {
    await FirebaseFirestore.instance.collection("Users").doc(userID).delete();
  } catch (e) {
    print("Error al eliminar los datos de Firestore: $e");
  }
}

¿Para qué sirve la función _reauthenticateAndDelete()?

La función _reauthenticateAndDelete() se utiliza para reautenticar al usuario antes de permitir ciertas operaciones sensibles, como eliminar la cuenta o modificar información crítica (correo electrónico, contraseña, etc.).

Firebase exige reautenticación si:

  1. El usuario intenta eliminar su cuenta o cambiar información sensible.
  2. La sesión del usuario es demasiado antigua: Aunque el usuario esté conectado, su sesión puede no ser considerada «reciente» para operaciones críticas.

Por esta razón, es importante incluir esta función en caso de que deleteUserAccount() devuelva el error «requires-recent-login».

Avatar de Pedro Cortez