'Flutter Injectable registers just dependencies under @module

I used Injectable, get_it with auto_route in a new flutter project. Accessing the dependencies registered as @modules works with no issues but any dependency annotated with @injectable, @singleton, @lazysingleton... throws an error at run time.

Error: FirebaseAuthProvider is not registered inside GetIt.

Below are my files and their contents

injectable.dart

final GetIt locator = GetIt.instance;

@InjectableInit()
Future<void> configureDependencies(String environment) async => await $initGetIt(locator, environment: environment);

main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await configureDependencies(Environment.dev);

  runApp(const App());
}

firebase_auth_provider.dart

@dev
@prod
@Singleton(as: AuthProvider, signalsReady: true)
class FirebaseAuthProvider implements AuthProvider {
  final FirestoreHelper collection = locator<FirestoreHelper>(param1: USERS_COLLECTION);
  final FirebaseAuth _firebaseAuth;

  FirebaseAuthProvider(this._firebaseAuth);

  Future<UserCredential> signInAnonymously() async {
    try {
      return await _firebaseAuth.signInAnonymously();
    } on FirebaseAuthException catch (e) {
      throw RequestError(message: ExceptionsFormatter.firebase(code: e.code));
    }

  }
...

Everything registered on this file works perfectly.

modules.dart

@module
abstract class CoreModules{
  @singleton
  AppRouter get appRouter => AppRouter(authGuard: AuthGuard());

  @lazySingleton
  FirebaseFirestore get firestore => FirebaseFirestore.instance;

  @lazySingleton
  FirebaseAuth get firebaseAuth => FirebaseAuth.instance;

  @lazySingleton
  Dio get dio => Dio();

  @prod
  @preResolve
  Future<FirebaseApp> get initFirebase async => await FirebaseService.init();

  @dev
  @preResolve
  Future<FirebaseService> get initDevFirebase async => await FirebaseService.initDev();
}

I wrote a guard for auto_route and anytime I run my app it throws an error trying to inject FirebaseAuthProvider

Error: FirebaseAuthProvider is not registered inside GetIt.

auth_guard.dart

class AuthGuard extends AutoRouteGuard{

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) async {
    FirebaseAuth firebaseAuth = locator<FirebaseAuth>();
    FirebaseAuthProvider firebaseAuthProvider = locator<FirebaseAuthProvider>();
    bool authenticated = firebaseAuth.currentUser == null;
    //
    if(!authenticated){
      await firebaseAuthProvider.signInAnonymously();
    }
    //
    locator<AppRouter>().replace(HomePageRoute(message: 'This is a test message from auth guard'));
    // resolver.next(true);
  }
}

I will provide more details if the context is still not very clear. Thank you for your contribution.



Solution 1:[1]

I figured the right way to invoke the FirebaseAuthProvider is via its abstract class. it's still not very clear to me, maybe because I am new to this pattern. But the code below works.

The right AuthProvider would be instantiated based on the environment you are working on.

class AuthGuard extends AutoRouteGuard{

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) async {
    FirebaseAuth firebaseAuth = locator<FirebaseAuth>();
    AuthProvider firebaseAuthProvider = locator<AuthProvider>();
    bool authenticated = firebaseAuth.currentUser != null;

    if(!authenticated){
      await firebaseAuthProvider.signInAnonymously();
    }

    locator<AppRouter>().replace(HomePageRoute(message: 'This is a test message from auth guard'));

  }
}

I also had to manually create the signInAnonymously method in the abstract class. That is not the design I was going for but I'll stick to that for now till I figure out a better way.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Limitless Claver