I am having a hard time understanding on how I can design a flutter screen with firebase authentication with multiple login method on the same screen. The Authentication screen (Auth_gate.dart) in my case should support:
My Firebase project as been initialised properly with Flutter.
My flutter project is well configured with firebase as per documentation. The in-built "SignInScreen" from the firebase_auth package is doing the job well for Google sign-in And email. https://firebase.flutter.dev/docs/ui/auth/integrating-your-first-screen/
Since it is working fine for Email and Google methods, I was thinking I can just add a new AppleProvider in the providers list, it will render the 'Sign in with apple' button and handle the flow like it did with Google.
I have set up my Apple developer to support the Apple Sign in method this is fine. https://firebase.google.com/docs/auth/ios/apple?authuser=0#enable-apple-as-a-sign-in-provider
In the Documentation of firebase, in the flutter section I only can find these line of code, I am note sure where to put them.
https://firebase.google.com/docs/auth/flutter/federated-auth
import 'package:firebase_auth/firebase_auth.dart';
Future<UserCredential> signInWithApple() async {
final appleProvider = AppleAuthProvider();
if (kIsWeb) {
await FirebaseAuth.instance.signInWithPopup(appleProvider);
} else {
await FirebaseAuth.instance.signInWithProvider(appleProvider);
}
}
It seems the SignInScreen do not support AppleProvider() because I am getting the following error:
The element type 'AppleAuthProvider' can't be assigned to the list type 'AuthProvider<AuthListener, AuthCredential>'. (Documentation)
I have consulted the following documentation links with not much insigths: https://firebase.flutter.dev/docs/ui/auth/building-a-custom-ui/ https://firebase.google.com/docs/auth/flutter/account-linking
Can someone explain what I am doing wrong? and how to get me back on track? Much appreciated.
main.dart
import 'dart:async';
import 'package:EcoClick/screens/auth_gate.dart';
import 'package:EcoClick/screens/on_boarding.dart';
import 'package:EcoClick/screens/permission_handler.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'languages/deleguates.dart';
import 'languages/localizations.dart';
import 'utils/database_helper.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
//Widget screen = const OnboardingScreen();
Widget screen = const AuthGate();
void main() {
runZonedGuarded(() async {
try {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final prefs = await SharedPreferences.getInstance();
final bool? look = prefs.getBool('look');
if (look == false || look == null) {
//screen = const OnboardingScreen();
} else {
//screen = const PermissionWrapper();
}
runApp(
Builder(
builder: (context) =>
Provider.value(
value: null,
builder: (context, child) => Greenprint(screen)),
),
);
}
catch (error) {
if (kDebugMode) {
print('error in main');
}
}
}, (Object e, StackTrace s) {
}, zoneSpecification: ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String message) {
},
));
}
class Greenprint extends StatelessWidget {
final Widget screen;
const Greenprint(this.screen, {super.key});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [ChangeNotifierProvider<MyDatabaseHelper>(
create: (_) => MyDatabaseHelper()),],
child: MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateTitle: (BuildContext context) =>
MyLocalizations
.of(context)
.homeTitle,
localizationsDelegates: const [
MyLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('fr', ''),
],
title: 'GreenPrint',
//theme: ThemeData.dark(),
home: screen,
),
);
}
}
auth_gate.dart
import 'package:EcoClick/screens/camera_widget.dart';
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'; // new
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
AppleAuthProvider test(){
var appleProvider = AppleAuthProvider();
appleProvider.addScope('email');
appleProvider.setCustomParameters({
'locale': 'fr',
});
FirebaseAuth.instance.signInWithPopup(appleProvider);
return appleProvider;
}
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: "0000000.apps.googleusercontent.com"), //OK
AppleAuthProvider() // Gives error: The element type 'AppleAuthProvider' can't be assigned to the list type 'AuthProvider<AuthListener, AuthCredential>'. (Documentation)
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('images/icon/icon.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const CameraScreen();
},
);
}
}
Well, kind of answering my own question! This helped a lot to understand. https://www.youtube.com/watch?v=dMS4TSFwml8&t=902s&ab_channel=ShivamGupta https://github.com/shivam22rkl/Google-Apple-SignIn/tree/main
Hope it helps, Cheers