Skip to content

Persistence growns without control #63

@JCKodel

Description

@JCKodel

On MacOS, every time I restart a project (i.e.: the 🔃 button on VSCode), a new persistence entry is added in firebase_auth.hive.

Currently, I have 24 entries that are all the same user (i.e.: every time the project starts, it loads the previous user from storage and then save it again, as a new row, making the firebase_auth.hive file to grow.

This is how I'm using it:

On main.dart:

await [
  FirebaseDartFlutter.setup(),
  dotenv.load(fileName: ".env.${kDebugMode ? "debug" : "release"}"),
].wait;

final firebaseOptions = FirebaseOptions(
  appId: dotenv.FIREBASE_APP_ID,
  apiKey: dotenv.FIREBASE_API_KEY,
  projectId: dotenv.FIREBASE_PROJECT_ID,
  messagingSenderId: dotenv.MESSAGING_SENDER_ID,
  authDomain: dotenv.FIREBASE_AUTH_DOMAIN,
  androidClientId: dotenv.FIREBASE_ANDROID_CLIENT_ID,
  iosBundleId: dotenv.FIREBASE_IOS_BUNDLE_ID,
  storageBucket: dotenv.FIREBASE_STORAGE_BUCKET,
  iosClientId: dotenv.FIREBASE_IOS_CLIENT_ID,
);

final tasks = await <Future<dynamic>>[
  I18n.loadLocale(),
  Firebase.initializeApp(options: firebaseOptions),
].wait;

final firebaseApp = tasks[1] as FirebaseApp;

await authService.initialize(firebaseApp);

So, basically, calling FirebaseDartFlutter.setup(), then Firebase.initializeApp(options: firebaseOptions), then initializing my authService as:

final class AuthService extends ChangeNotifier {
  AuthService._();

  final _logger = Logger("${AuthService}");
  late final FirebaseAuth _firebaseAuth;

  String _userId = "";
  String get userId => _userId;
  Completer<User?>? _initializationCompleter;

  Future<void> initialize(FirebaseApp firebaseApp) async {
    _logger.info("Initializing ${AuthService}");
    _firebaseAuth = FirebaseAuth.instanceFor(app: firebaseApp);
    _initializationCompleter = Completer<User?>();
    _firebaseAuth.authStateChanges().listen(_onAuthStateChanged);
    await _initializationCompleter!.future;
    _initializationCompleter = null;
    _userId = _firebaseAuth.currentUser?.uid ?? "";
  }

  void _onAuthStateChanged(User? user) {
    if (_initializationCompleter != null) _initializationCompleter!.complete(user);

    if (user == null && _userId.isNotEmpty) {
      _userId = "";
      notifyListeners();
    }
  }

Needed to add that Completer hack because of #62

So, every time the project starts or I restart it from the 🔃 button on VSCode, a new entry is added to the hive database (there is no operation whatsoever, no new login or logout).

EDIT:

I think the code responsible to write to persistence is

Future<void> setCurrentUser(User? currentUser) async {
, which is, in theory, correct.

But, somehow, hive is saving the same ID repeatedly:

Image

Because of this, currently, my firebase_auth.hive is 80Kb (and there is only a single login with email and password).

EDIT 2:

final hiveBox = await Hive.openBox<String>("firebase_auth");

await hiveBox.compact();

This solves the issue. I recommend to compact the database on initialization (or after storing the user), so it would not grow unchecked. Or, better yet, stop using Hive (it sucks, a lot, alternative: https://pub.dev/packages/reaxdb_dart or just write in SharedPreferences) Better yet: let us handle persistence by implementing an interface (NHost does that with an interface https://github.com/nhost/nhost-dart/blob/main/packages/nhost_sdk/lib/src/base/auth_store.dart that can be provided to the initialization method: https://github.com/nhost/nhost-dart/blob/04142ec5b6d3a3340480f46b93c2ec72f1939f43/packages/nhost_flutter_auth/example/lib/persistent_auth_example.dart#L47) (so, in case we could use something like https://pub.dev/packages/flutter_secure_storage).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions