Social Sign-In: Apple, Facebook & GitHub
Social Sign-In: Apple, Facebook & GitHub
Adding social sign-in providers dramatically improves conversion rates by letting users authenticate with accounts they already trust. This lesson covers integrating Apple Sign-In (mandatory for iOS apps that offer any third-party login), Facebook Login, and GitHub OAuth into Firebase Authentication. Each provider has unique platform configuration requirements, but they all follow the same high-level pattern: obtain an OAuth credential from the provider's SDK, then pass it to Firebase to create or link an account.
Apple Sign-In
Apple Sign-In uses the sign_in_with_apple package on Flutter alongside the firebase_auth credential flow. The setup involves both Xcode configuration and Firebase Console changes.
iOS / Xcode setup:
- In Xcode, open Signing & Capabilities and add the Sign In with Apple capability.
- In the Firebase Console, enable the Apple provider under Authentication → Sign-in method and supply your Apple Services ID, Team ID, Key ID, and the private key (.p8 file) from Apple Developer.
- Register a Services ID in your Apple Developer account and configure the
Return URLto the Firebase OAuth redirect URL shown in the console.
Android setup (optional but recommended): Apple Sign-In on Android routes through a web-based flow. Add the redirect URI to your Apple Services ID, and register the SHA-1 fingerprint of your Android app in Firebase.
Apple Sign-In — Flutter implementation
import 'package:firebase_auth/firebase_auth.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'dart:convert';
import 'dart:math';
// Generate a cryptographically secure nonce
String _generateNonce([int length = 32]) {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
// SHA-256 hash a nonce (import crypto package)
// String _sha256ofString(String input) { ... }
Future<UserCredential?> signInWithApple() async {
final rawNonce = _generateNonce();
// final nonce = _sha256ofString(rawNonce); // hash before sending to Apple
try {
final appleCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
// nonce: nonce, // pass hashed nonce to Apple
);
final oauthCredential = OAuthProvider('apple.com').credential(
idToken: appleCredential.identityToken,
rawNonce: rawNonce, // pass RAW nonce to Firebase
);
return await FirebaseAuth.instance.signInWithCredential(oauthCredential);
} on SignInWithAppleAuthorizationException catch (e) {
if (e.code == AuthorizationErrorCode.canceled) {
return null; // user dismissed the sheet
}
rethrow;
}
}
appleCredential.givenName and appleCredential.familyName immediately on first login — subsequent authentications return null for these fields.Facebook Login
Facebook Login uses the official flutter_facebook_auth package. You must create a Facebook App in the Meta for Developers portal and whitelist your bundle ID (iOS) and package name + key hash (Android).
Setup steps:
- Add your app to the Meta Developer Portal, get the App ID and App Secret.
- In Firebase Console, enable the Facebook provider and paste in your App ID and App Secret.
- Add the
facebook_app_idandfacebook_client_tokentoAndroidManifest.xmlandInfo.plistas required by the package docs. - For Android, generate the release key hash with
keytooland add it to the Facebook App dashboard under Android → Key Hashes.
Facebook Sign-In — Flutter implementation
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
Future<UserCredential?> signInWithFacebook() async {
// Trigger the Facebook sign-in flow
final LoginResult loginResult = await FacebookAuth.instance.login(
permissions: ['email', 'public_profile'],
);
if (loginResult.status == LoginStatus.cancelled) {
return null;
}
if (loginResult.status != LoginStatus.success) {
throw Exception('Facebook login failed: ${loginResult.message}');
}
// Obtain the access token
final AccessToken accessToken = loginResult.accessToken!;
// Create a Facebook credential for Firebase
final OAuthCredential facebookCredential =
FacebookAuthProvider.credential(accessToken.tokenString);
// Sign in to Firebase with the Facebook credential
return FirebaseAuth.instance.signInWithCredential(facebookCredential);
}
// Fetch profile data (optional — Facebook returns basic profile via Firebase)
Future<Map<String, dynamic>> getFacebookUserData() async {
final userData = await FacebookAuth.instance.getUserData(
fields: 'name,email,picture.width(200)',
);
return userData;
}
GitHub OAuth
GitHub does not have a dedicated Flutter package. Instead, you use Firebase's GithubAuthProvider with a custom OAuth web flow, typically via signInWithPopup on web or a deep-link redirect flow on mobile.
Setup steps:
- Register an OAuth App in GitHub Settings → Developer settings. Set the Authorization Callback URL to the Firebase OAuth redirect URL.
- Enable the GitHub provider in Firebase Console (Authentication → Sign-in method) and paste your GitHub Client ID and Client Secret.
- On mobile, use the
firebase_dynamic_linksor a custom URL scheme to handle the redirect back to the app after GitHub authorization.
GitHub Sign-In — using signInWithProvider (Flutter Web & mobile)
import 'package:firebase_auth/firebase_auth.dart';
Future<UserCredential?> signInWithGitHub() async {
final githubProvider = GithubAuthProvider();
// Request additional scopes if needed
githubProvider.addScope('read:user');
githubProvider.addScope('user:email');
try {
// On Web: opens a popup; on mobile: redirects through browser
final UserCredential credential =
await FirebaseAuth.instance.signInWithProvider(githubProvider);
return credential;
} on FirebaseAuthException catch (e) {
if (e.code == 'account-exists-with-different-credential') {
// Handle credential linking (see section below)
await _linkGitHubToExistingAccount(e);
return null;
}
rethrow;
}
}
Future<void> _linkGitHubToExistingAccount(FirebaseAuthException e) async {
// Fetch which providers are registered for this email
final email = e.email!;
final methods = await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);
// Prompt user to sign in with existing provider, then link
debugPrint('Sign in first with: $methods, then link GitHub.');
}
Credential Linking
A user who has previously signed in with email/password may try to sign in again with a social provider that shares the same email. Firebase throws account-exists-with-different-credential. The correct resolution is to:
- Sign the user in with their original provider.
- Call
user.linkWithCredential(pendingCredential)to attach the new social provider to the existing account. - From that point on, the user can sign in with either method.
Summary
In this lesson you learned how to integrate three social sign-in providers into a Flutter app using Firebase Authentication:
- Apple Sign-In — mandatory for iOS App Store apps offering third-party login; uses a secure nonce, requires Xcode capability + Firebase configuration + Apple Developer Services ID.
- Facebook Login — uses the
flutter_facebook_authpackage; requires a Meta Developer App, bundle IDs, key hashes, and credentials in Firebase Console. - GitHub OAuth — no dedicated SDK; use
GithubAuthProviderwithsignInWithProvider; requires a GitHub OAuth App and the redirect callback URL configured in Firebase.
All three follow the same credential-handoff pattern: obtain a provider token, wrap it in a Firebase OAuthCredential, then call signInWithCredential. Handle the account-exists-with-different-credential error everywhere social sign-in is used to avoid duplicate accounts.