I am trying to create a single interface for Google and Facebook login, my SignInProvider
looks like:
abstract class SignInProvider with ChangeNotifier {
bool get isSigningIn;
set isSigningIn(bool isSigningIn);
void login();
void logout();
}
class FacebookSignInProvider with ChangeNotifier implements SignInProvider { ... }
class GoogleSignInProvider with ChangeNotifier implements SignInProvider { ... }
My Landing page:
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<SignInProvider>(create: (context) => GoogleSignInProvider()),
ChangeNotifierProvider<SignInProvider>(create: (context) => FacebookSignInProvider())
],
child: Scaffold(
body: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
final provider =
Provider.of<SignInProvider>(context, listen: true);
if (provider.isSigningIn) {
return // Show loader
} else if (snapshot.hasData) {
return // Show logged-in UI
} else {
// Give option to login via Google and Facebook
return Row(children: [
TextButton(
onPressed: () {
final provider = Provider.of<SignInProvider>(
context,
listen: false,
);
provider.login();
},
child: const Text('Login with Google'),
),
TextButton(
onPressed: () {
final provider = Provider.of<SignInProvider>(
context,
listen: false,
);
provider.login();
},
child: const Text('Login with Facebook'),
),
],
);
}
}),
),
);
}
}
In this UI, clicking on Login with Google
and Login with Facebook
both are referring to FacebookSignInProvider
, since that is provided last in the list of providers. How can I make it act on respective provider?
When I change the onPressed
definition to Provider.of<GoogleSignInProvider>
or Provider.of<FacebookSignInProvider>
it crashes.
3
Answers
Replace
ChangeNotifierProvider<SignInProvider>
withChangeNotifierProvider< FacebookSignInProvider>
andChangeNotifierProvider<GoogleSignInProvider>
Link to the output
Try this solution
Create a single generic SignInProvider with ChangeNotifier along with SignInType enum
Create _HomeState class as follows
This way you will have a more generic provider that can handle multiple type of login providers.
You can also create separate abstract class following the above pattern.
Hope it helps.
Thanks 🙂