Reputation: 546
I've integrated an Apple sign in for Flutter.
Everything is working fine until the point when I have to logout from the Stores() page.
The app landing page (Home) shows a series of buttons to login with different apps:
All of them are able to logout by using a logout button, but not Apple.
Here is my code
main.dart
class Main extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthService().user,
child: MaterialApp(
home: Wrapper(),
routes: {
"/stores": (_) => Stores()
},
));
}
}
Wrapper.dart
class Wrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
if (user == null) {
return Home(); <-- Landing page before login
} else {
return Stores(); <-- Landing page after login, where the logout button is
}
}
}
Home.dart
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
bool loading = false;
final welcomeText = 'Welcome';
final subtitle = 'Make grocery chores easier';
final anonymousButtonText = 'Skip';
@override
Widget build(BuildContext context) {
return Stack(children: [
AuthLayout(),
Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: Center(child: Text(welcomeText)),
backgroundColor: Colors.transparent,
),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget> [
// Sign In with Apple
Padding(
padding: EdgeInsets.all(8.0),
child: FutureBuilder<Object>(
future: _auth.appleSignInAvailable,
builder: (context, snapshot) {
if (snapshot.data == true) {
return AppleSignInButton(
onPressed: () async {
FirebaseUser user =
await _auth.appleSignIn();
if (user != null) {
Navigator.pushReplacementNamed(context, "/stores");
}
},
);
} else {
return Container();
}
})) ....
AuthService.dart
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();
// Create user object based on FirebaseUser
User _userFromFirebaseUser(FirebaseUser user) {
return user != null ? User(uid: user.uid) : null;
}
// Auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged.map(
_userFromFirebaseUser);
}
// SignIn with Google
Future signInGoogle() async {
GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
AuthCredential credential = GoogleAuthProvider.getCredential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken);
try {
AuthResult result = (await _auth.signInWithCredential(credential));
FirebaseUser user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// SignIn with Apple
// Determine if Apple Signin is available on device
Future<bool> get appleSignInAvailable => AppleSignIn.isAvailable();
Future appleSignIn() async {
try {
final AuthorizationResult appleResult =
await AppleSignIn.performRequests([
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
]);
if (appleResult.error != null) {
// handle error from Apple
}
final AuthCredential credential = OAuthProvider(providerId: 'apple.com')
.getCredential(
accessToken: String.fromCharCodes(
appleResult.credential.authorizationCode),
idToken:
String.fromCharCodes(appleResult.credential.identityToken));
AuthResult result = (await _auth.signInWithCredential(credential));
FirebaseUser user = result.user;
return user;
} catch (error) {
print(error);
return null;
}
}
// SignOut
Future signOut() async {
try {
return await _auth.signOut(); <-- Should I do something different here for Apple?
} catch (e) {
print(e.toString());
return null;
}
}
}
All the other apps logout correctly, but Apple doesnt. Should I do something different in the signout since it's using /routes?
Any help is much appreciated!!
Many thanks
Joe
Upvotes: 10
Views: 4042
Reputation: 1
Should be fine, make sure that you have followed the steps described here:
https://firebase.google.com/docs/auth/ios/apple
Which means your application needs to fulfill the following requirements to make apple sign in work properly:
Upvotes: 0
Reputation: 1230
await _firebaseAuth.signOut();
Use the above code for signout and check firebase IOS configuration
Upvotes: 1