Facebook login flutter app error with native login - facebook

I am trying to integrate facebook login with Flutter. Facebook login working with FacebookLoginBehavior.webViewOnly but I want to login with native dialog. This is not woking in flutter. (iOS only)....
Future<bool> facebookLogin(
BuildContext context, bool isCoach, AuthMode authMode) async {
final facebookLogin = FacebookLogin();
facebookLogin.loginBehavior = FacebookLoginBehavior.nativeOnly;
final result = await facebookLogin.logInWithReadPermissions(['email']);
print(result.status);
if (result.status == FacebookLoginStatus.loggedIn) {
var _token = result.accessToken.token;
return true;
}
return false;
}
Logs: flutter: FacebookLoginStatus.cancelledByUser

As per the issue list for the plugin this is a bug for iOS 13 (https://github.com/roughike/flutter_facebook_login/issues/195)
Use the device_info package and you can put the following check for the iOS 13 device so the rest of the world enjoys the native view
if (Platform.isIOS){
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
String iosSystemVersion = iosInfo.systemVersion;
if (iosSystemVersion.startsWith('13')){
print('Running on IOS version $iosSystemVersion. Forcing facebook login to be webViewOnly');
_facebookSignIn.loginBehavior = FacebookLoginBehavior.webViewOnly;
}
}

Related

How to register biometric fingerprint in flutter app

Is there a way to register user biometric directly from flutter app?
Use this package https://pub.dev/packages/local_auth
Check if the device supports biometrics
import 'package:local_auth/local_auth.dart';
// ···
final LocalAuthentication auth = LocalAuthentication();
// ···
final bool canAuthenticateWithBiometrics = await auth.canCheckBiometrics;
final bool canAuthenticate =
canAuthenticateWithBiometrics || await auth.isDeviceSupported();
To authenticate use
final bool didAuthenticate = await auth.authenticate(
localizedReason: 'Please authenticate to show account balance',
options: const AuthenticationOptions(biometricOnly: true));

Is there any way i can get the name of the user of the phone(android) in flutter app?

Guys I am trying to get the name of the user who uses the phone. Is there any flutter plugin which can provide me this functionality
Hello you can use this plugin device_info, you can see the documentation about it here :
https://pub.dev/packages/device_info#-example-tab-
import 'package:device_info/device_info.dart';
void getDeviceinfo() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidDeviceInfo = await deviceInfo.androidInfo; // instantiate Android Device Information
IosDeviceInfo iosInfo = await deviceInfo.iosInfo; // instantiate IOS Device Information
print("for Android : ${androidDeviceInfo.product}");
print("for IOS : ${iosInfo.name}");
}

How to connect facebook, firebase and flutter?

I'm following the instructions for incorporating facebook with android projects found here https://developers.facebook.com/apps/318154048893918/fb-login/quickstart/ and there is a step to download the Facebook SDK, but after that, it doesn't tell me where to put the file. The import statement it tells me to add won't work (says target of uri doesn't exist).
I'm trying to add the facebook user to our firebase database when they log in. I'm using flutter in android studio.
There doesn't seem to be anything of use in the console log, except that print statement doesn't print anything. Any ideas?
Here's my code to log in the user.
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
Future<FirebaseUser> initiateFacebookLogin() async {
final FacebookLoginResult result =
await facebookLogin.logInWithReadPermissions(['email', 'public_profile']);
FirebaseUser user =
await _auth.signInWithFacebook(accessToken: result.accessToken.token);
//Token: ${accessToken.token}
ProviderDetails userInfo = new ProviderDetails(
user.providerId, user.uid, user.displayName, user.photoUrl, user.email);
List<ProviderDetails> providerData = new List<ProviderDetails>();
providerData.add(userInfo);
print(user.displayName);
addToDatabase(user.uid, user.displayName, user.displayName, user.email);
return user;
}
In flutter you need use flutter_facebook_login plugin take a look here to see how to get the plugin and setup your flutter app to make use of this plugin. You can also check this article that is step-by-step about how setup you project and contains code example too but the API used is out of date.
Here a snippet with updated API showing how to achieve login in firebase with facebook account.
/// This mehtod makes the real auth
Future<FirebaseUser> firebaseAuthWithFacebook({#required FacebookAccessToken token}) async {
AuthCredential credential= FacebookAuthProvider.getCredential(accessToken: token.token);
FirebaseUser firebaseUser = await _authInstance.signInWithCredential(credential);
return firebaseUser;
}
In your code you're using _auth.signInWithFacebook method that is deprecated and you should replaced by signInWithCredential updating you firebase_auth plugin version.
///This object comes from facebook_login_plugin package
final facebookLogin = new FacebookLogin();
final facebookLoginResult = await facebookLogin
.logInWithReadPermissions(['email', 'public_profile']);
switch (facebookLoginResult.status) {
case FacebookLoginStatus.error:
print("Error");
break;
case FacebookLoginStatus.cancelledByUser:
print("CancelledByUser");
break;
case FacebookLoginStatus.loggedIn:
print("LoggedIn");
/// calling the auth mehtod and getting the logged user
var firebaseUser = await firebaseAuthWithFacebook(
token: facebookLoginResult.accessToken);
}
}

Auth0-How to use with Flutter

I need use Auth0 with Flutter but there is no such SDK in Auth0 site.
Auth0 works to create such SDK for Flutter.
Did anyone use Auth0 with Flutter or what can you advise?
Its very simple to get started with flutter auth0
Have a class for auth0 and call this at the places you need them. But also be sure to set the constants AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_REDIRECT_URI, AUTH0_ISSUER
class Auth0 {
final FlutterAppAuth appAuth = FlutterAppAuth();
Map<String, Object> parseIdToken(String idToken) {
final List<String> parts = idToken.split('.');
assert(parts.length == 3);
return jsonDecode(
utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))));
}
Future<Map<String, Object>> getUserDetails(String accessToken) async {
const String url = 'https://$AUTH0_DOMAIN/userinfo';
final http.Response response = await http.get(
url,
headers: <String, String>{'Authorization': 'Bearer $accessToken'},
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get user details');
}
}
Future<void> loginAction() async {
isBusy = true;
errorMessage = 'Error! - ';
try {
final AuthorizationTokenResponse result =
await appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
AUTH0_CLIENT_ID,
AUTH0_REDIRECT_URI,
issuer: 'https://$AUTH0_DOMAIN',
scopes: <String>['openid', 'email', 'profile', 'offline_access'],
promptValues: ['login']
),
);
final Map<String, Object> idToken = parseIdToken(result.idToken);
final Map<String, Object> profile =
await getUserDetails(result.accessToken);
isBusy = false;
name = idToken['name'];
email = profile['email'];
picture = profile['picture'];
} on Exception catch (e, s) {
print('login error: $e - stack: $s');
isBusy = false;
errorMessage = e.toString();
}
}
Instead of using a boolean for checking isLoggedIn try saving the token in the localstorage and that will set the state as is.
There's an auth0 package for flutter to use Auth0 API provides login, logout and access APIs for authentication in your App. However, you need to make changes inside android and ios files in your flutter project. You need to configure your callbacks and application settings for that, The author has their example on github that you should check out.
I would advise you to follow the blog post provided by the Auth0 team -
Get Started with Flutter Authentication
For Flutter Web App, I am making a wrapper around Auth0 JS SPA SDK.
GitHub: https://github.com/anthonychwong/auth0-flutter-web
Pub.dev: https://pub.dev/packages/auth0_flutter_web
import 'package:auth0_flutter_web/auth0_flutter_web.dart';
Auth0 auth0 = await createAuth0Client(
Auth0CreateOptions(
domain: '-- domain of the universal login page --',
client_id: '-- id of your app --',
)
);
String token = await auth0.getTokenWithPopup();
It is in very early stage and PRs are welcome.

How to get unique device id in flutter?

In Android we have, Settings.Secure.ANDROID_ID. I do not know the iOS equivalent.
Is there a flutter plugin or a way to get a unique device id for both Android and IOS in flutter?
Null safe code
Use device_info_plus plugin developed by Flutter community. This is how you can get IDs on both platform.
In your pubspec.yaml file add this:
dependencies:
device_info_plus: ^3.2.3
Create a method:
Future<String?> _getId() async {
var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { // import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else if(Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo;
return androidDeviceInfo.androidId; // unique ID on Android
}
}
Usage:
String? deviceId = await _getId();
There is a plugin called device_info. You can get it here.
Check the official example here
static Future<List<String>> getDeviceDetails() async {
String deviceName;
String deviceVersion;
String identifier;
final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
try {
if (Platform.isAndroid) {
var build = await deviceInfoPlugin.androidInfo;
deviceName = build.model;
deviceVersion = build.version.toString();
identifier = build.androidId; //UUID for Android
} else if (Platform.isIOS) {
var data = await deviceInfoPlugin.iosInfo;
deviceName = data.name;
deviceVersion = data.systemVersion;
identifier = data.identifierForVendor; //UUID for iOS
}
} on PlatformException {
print('Failed to get platform version');
}
//if (!mounted) return;
return [deviceName, deviceVersion, identifier];
}
You can store this UUID in the Keychain. This way you can set an unique ID for your device.
UPDATE
device_info is now device_info_plus
I just published a plugin to provide a solution to your problem.
It uses Settings.Secure.ANDROID_ID for Android and relies on identifierForVendor and the keychain for iOS to make the behaviour equivalent to Android's.
Here's the link.
Update 1/3/2021: The recommended way is now the extended community plugin called device_info_plus. It supports more platforms than device_info and aims to support all that are supported by flutter. Here is an example usage:
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';
Future<String> getDeviceIdentifier() async {
String deviceIdentifier = "unknown";
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceIdentifier = androidInfo.androidId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
deviceIdentifier = iosInfo.identifierForVendor;
} else if (kIsWeb) {
// The web doesnt have a device UID, so use a combination fingerprint as an example
WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
deviceIdentifier = webInfo.vendor + webInfo.userAgent + webInfo.hardwareConcurrency.toString();
} else if (Platform.isLinux) {
LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
deviceIdentifier = linuxInfo.machineId;
}
return deviceIdentifier;
}
Use device_id plugin
Add in your following code in your .yaml file.
device_id: ^0.1.3
Add import in your class
import 'package:device_id/device_id.dart';
Now get device id from:
String deviceid = await DeviceId.getID;
I release a new flutter plugin client_information might help. It provide a simple way to get some basic device information from your application user.
add to pubspec.yaml
dependencies:
...
client_information: ^1.0.1
import to your project
import 'package:client_information/client_information.dart';
then you can get device ID like this
/// Support on iOS, Android and web project
Future<String> getDeviceId() async {
return (await ClientInformation.fetch()).deviceId;
}
As of 2022, December, last status about getting device id :
device_info_plus don't give unique device id anymore. So I started to use platform_device_id package.
I tested it on Android and it worked as same as device_info previously and provide the same id value. It also has a simple usage :
String deviceId = await PlatformDeviceId.getDeviceId;
This package uses updated android embedding version and also has null safety support.
Latest:
The plugin device_info has given deprecation notice and replaced by
device_info_plus
Example:
dependencies:
device_info_plus: ^2.1.0
How to use:
import 'package:device_info_plus/device_info_plus.dart';
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
print('Running on ${androidInfo.model}'); // e.g. "Moto G (4)"
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
print('Running on ${iosInfo.utsname.machine}'); // e.g. "iPod7,1"
WebBrowserInfo webBrowserInfo = await deviceInfo.webBrowserInfo;
print('Running on ${webBrowserInfo.userAgent}'); // e.g. "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"
You can check here full example:
For Unique ID:
You can use following code to get Unique ID:
if (kIsWeb) {
WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
deviceIdentifier = webInfo.vendor +
webInfo.userAgent +
webInfo.hardwareConcurrency.toString();
} else {
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceIdentifier = androidInfo.androidId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
deviceIdentifier = iosInfo.identifierForVendor;
} else if (Platform.isLinux) {
LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
deviceIdentifier = linuxInfo.machineId;
}
}
edit: There is no androidId on since v4.1.0.
androidID is removed since v4.1.0. Check the changelog.
android_id package is recommanded to get the correct androidId.
Add the following code in your .yaml file.
device_info_plus: ^1.0.0
I used the following approach to get the device info that support in all platforms (i.e.) Android, IOS and Web.
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
Future<String> getDeviceIdentifier() async {
String deviceIdentifier = "unknown";
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (kIsWeb) {
WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
deviceIdentifier = webInfo.vendor +
webInfo.userAgent +
webInfo.hardwareConcurrency.toString();
} else {
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceIdentifier = androidInfo.androidId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
deviceIdentifier = iosInfo.identifierForVendor;
} else if (Platform.isLinux) {
LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
deviceIdentifier = linuxInfo.machineId;
}
}
return deviceIdentifier;
}
Use device_info_plus package developed by Flutter community. This is how you can get IDs on both platform.
In your pubspec.yaml file add this:
dependencies:
device_info_plus: ^3.2.3
Create a method:
Future<String> getUniqueDeviceId() async {
String uniqueDeviceId = '';
var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { // import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
uniqueDeviceId = '${iosDeviceInfo.name}:${iosDeviceInfo.identifierForVendor}'; // unique ID on iOS
} else if(Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo;
uniqueDeviceId = '${androidDeviceInfo.name}:${androidDeviceInfo.id}' ; // unique ID on Android
}
return uniqueDeviceId;
}
Usage:
String deviceId = await getUniqueDeviceId();
Output:
M2102J20SG::SKQ1.211006.001
Note:
Do not use androidDeviceInfo.androidId. This would change when your mac address changes. Mobile devices above Android OS 10/11 will generate a randomized MAC. This feature is enabled by default unless disabled manually. This would cause the androidId to change when switiching networks. You can confirm this by yourself by changing androidDeviceInfo.id to androidDeviceInfo.androidId above.
you can probably get away with using only androidDeviceInfo.name as it would not change ever.
androidDeviceInfo.id can also change if OS is updated as it is an android os version.
androidDeviceInfo.androidId should only be used if device uses fix mac address as mentioned in point 1. Otherwise, either use *.name only or androidDeviceInfo.id alongside with *.name.
android_id: ^0.1.3+1
Use this package but it only works on android.
device_info_plus: ^8.0.0
Use this package it works on IOS, Android, Web.
If you're serving ads you can use ASIdentifierManager. You should only use it for ads. There is no general UDID mechanism provided by the OS on iOS, for privacy reasons.
If you're using firebase_auth plugin you could signInAnonymously and then use the id of the FirebaseUser. This will give you an identifier that is specific to your Firebase app.