Skip to content

Instantly share code, notes, and snippets.

@michael-wang
Created September 7, 2023 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michael-wang/180445c1f1755057f933fb323c424776 to your computer and use it in GitHub Desktop.
Save michael-wang/180445c1f1755057f933fb323c424776 to your computer and use it in GitHub Desktop.
[riverpod] Auth async provider as Listener (for RoRouter.refreshListenable)
part 'auth.g.dart';
// The key to become Listenable, is to implement Listenable...
// And notify listener when state changed of course.
@Riverpod(keepAlive: true)
class Auth extends _$Auth implements Listenable {
VoidCallback? _callback;
@override
void addListener(VoidCallback listener) {
_callback = listener;
}
@override
void removeListener(VoidCallback listener) {
if (_callback == listener) {
_callback = null;
}
}
@override
FutureOr<User?> build() async {
// Listen to self so we can notify listener's callback.
ref.listenSelf((_, __) {
if (state.isLoading) return;
_callback?.call();
});
// Listen to Firebase auth state.
fb.FirebaseAuth.instance.authStateChanges().listen(_firebaseAuthListener);
return null;
}
signIn(String email, String password) async {
await fb.FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
}
signOut() async {
await fb.FirebaseAuth.instance.signOut();
}
void _firebaseAuthListener(fb.User? fbUser) async {
update((_) async {
// Convert Firebase user to domain user.
return fbUser == null ? null : DomainUser(fbUser);
});
}
}
viud main() {
runApp(
ProviderScope(
child: App(),
),
);
}
class App extends ConsumerWidget with ScreenMixin {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return ref.watch(routerProvider()).when(
data: (router) {
return MaterialApp.router(
routerConfig: router,
// ...
);
},
error: //...
loading: //...
);
}
}
part 'router.g.dart';
@riverpod
FutureOr<Raw<GoRouter>> router(RouterRef ref) async {
final user = await ref.watch(authProvider.future);
return GoRouter(
refreshListenable: ref.watch(authProvider.notifier),
routes: [
//...
],
redirect: (context, state) {
final signedIn = user != null;
// redirect according to signed-in state.
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment