'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 |
