flutter_facebook_login
package (https://pub.dev/packages/flutter_facebook_login) is used to integrate facebook login with Flutter
It provides FacebookLogin().logIn()
method which redirects a user to login to Facebook via webview of default browser and grant permission to application to access profile information
Import flutter_facebook_login
module for facebook login and flutter_auth_buttons
for FacebookSignInButton
import 'package:flutter_auth_buttons/flutter_auth_buttons.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
logIn
function takes an array of entities representing private data like 'email' for which permission is to be requested
final facebookLogin = FacebookLogin();
final token = await facebookLogin.logIn(['email']).accessToken.token;
Use access token returned by logIn()
after a valid login to send graph api request
final graphResponse = await http.get('https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${token}');
// decode http response body
final profile = json.decode(graphResponse.body);
It contains a user id which can be used to create a user account in Firebase for the application or can be sent to a private server with custom implementation of user accounts
await facebookLogin.logOut()
Check Flutter installation to setup Flutter
Use flutter create
command to create a Flutter project (here named nc_fb_login) :
flutter create nc_fb_login
Login to https://developers.facebook.com/ and click on MyApps
Click on Create a new app
Select an option which mentions Facebook Login (option 3)
Enter app id which should not contain Facebook trademark or brand elements like fb, and click Create App ID
Go to Facebook application dashboard and click on Set up under Facebook Login and select Android platform
Alternatively, go to https://developers.facebook.com/docs/facebook-login/android and select app
Skip the step of downloading Facebook Sdk
To integrate sdk, edit build.gradle
of android app and add provided dependency
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.facebook.android:facebook-android-sdk:[5,6)'
}
Enter Package Name and Default Activity Class Name which is typically <package name>.MainActivity
Package name can be found in nc_fb_login(flutter app name)/android/app/src/main/AndroidManifest.xml
Click on save
If a prompt is displayed mentioning problem verifying package name on Google Play, click on use this package name
To add Development key hash, use the provided command
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
This works in Linux, and returns a base64 value of sha1 hash
Paste it and click on Save
Enabling single sign on is optional
Next step is to add FacebookActivity in AndroidManifest and provided strings in strings.xml
Create strings.xml and add provided xml strings to
<resources>
<string name="app_name">NcFcbkLoginApp</string>
<string name="facebook_app_id">567309393944105</string>
<string name="fb_login_protocol_scheme">fb567309393944105</string>
</resources>
app_name seemingly was not required to match flutter or Facebook application name
Add provided metadata and activity in AndroidManifest before closing application tag (</application>)
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.nc_fb_login">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="io.flutter.app.FlutterApplication" android:label="nc_fb_login" android:icon="@mipmap/ic_launcher">
<activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme"/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data android:name="flutterEmbedding" android:value="2"/>
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
</application>
</manifest>
Add flutter_facebook_login and flutter_auth_buttons package to pubspec.yaml
dependencies:
flutter_facebook_login:
flutter_auth_buttons:
flutter:
sdk: flutter
Run following command to add dependency
flutter pub get
import 'package:flutter/material.dart';
// for json.decode()
import 'dart:convert';
// for async keyword
import 'dart:async';
// to send facebook graph api request
import 'package:http/http.dart' as http;
// for FacebookSignInButton
import 'package:flutter_auth_buttons/flutter_auth_buttons.dart';
// to initiate Facebook webview login
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
void main() => runApp(new MaterialApp(
title: 'Flutter Authentication App',
home: new LoginPage(),
));
class LoginPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
final facebookLogin = FacebookLogin();
// state variable to store profile data
var _fbUser;
// onPressed handler for FacebookSignInButton
Future<dynamic> _handleSignIn() async {
// facebookLogin.logIn() redirects user to login webview of Facebook (using default browser)
final result = await facebookLogin.logIn(['email']);
// get token from response (assuming user doesn't cancel login workflow)
final token = result.accessToken.token;
// send facebook graph api request to get name, picture and email
final graphResponse = await http.get(
'https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${token}');
// decode http response body
final profile = json.decode(graphResponse.body);
// print(profile);
// set state with profile data
this.setState((){_fbUser= profile;});
}
Widget renderButton() {
return Center(
child: FacebookSignInButton(
onPressed: this._handleSignIn,
textStyle: TextStyle(
fontSize: 14,
color: Colors.white,
),
),
);
}
Widget renderUser() {
return Center(
child: Column(
// to center vertically
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container( height:200, width:200, child: Card( child:Image.network(_fbUser["picture"]["data"]["url"], fit: BoxFit.cover))),
Container(
padding: EdgeInsets.only(top:20),
child: Column(
children: [
Text('Name: ${_fbUser["name"]}'),
Text('Email: ${_fbUser["email"]}'),
],
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
// render button if user data is not available, else render retrieved user profile data
var render = _fbUser == null? renderButton() : renderUser();
return new Scaffold(
appBar: new AppBar(title: new Text('Facebook Login'),),
body: new Container(
child: render,
),
);
}
}
_fbUser
) as state Ensure a supported device is connected or emulator is started
Go to project directory
Use flutter run
command to run
flutter run
It builds and runs app on an available android/ios device