Closed itssidhere closed 2 years ago
This is from the facebook documentation.
To avoid a disrupted user experience, please use the following checklist: Ensure that you have upgraded to version 8.2.0 (or later) of the Facebook SDK for Android. If your app is built to target Android 11 (API level 30) and your users are on Android 11, alternative non-webview login mechanisms provided by the SDK will not work unless you upgrade to or past 8.2.0.
flutter_facebook_auth: ^3.5.0
uses the facebook sdk 11.0.0
I have updated flutter_facebook_auth to 3.5.1
to use the android facebook sdk 11.1.1
but I think that you should open the issue here https://github.com/facebook/facebook-android-sdk because the issue is not this plugin
@darwin-morocho have you seen this?
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
@darwin-morocho have you seen this?
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
This plugin does not start an activity maybe the facebook sdk on Android has this functionality so the issue is from the native sdk, in that case if we need to add some extra code in this plugin (Android side) please add a documentation of facebook or any other source related with this
@darwin-morocho Can we bubble up the exception by the SDK from method channel to the app? So we can handle the error by ourselves because right now it just crashes the app. I tried using try catch block but I think error is not bubbling up into the dart code.
If the app is working fine in debug mode maybe the problem is your release key hash in the console or any missing configuration in the Facebook developers console. Actually the plataform channels catch all events and errors according to Facebook documentacion. Unfortunally i don't have an Android 11 device to replicate the problem because I use a mac with M1 chip
Actually the app crashes in mi phones most of the time, works good on Samsung
Actually the app crashes in mi phones most of the time, works good on Samsung
according to your medium link you must add the queries for the Facebook app adding the Facebook package name or you can use loginBehavior parameter in the login method and use default falkback or webview when you app is running Android 11 or higher
@itssidhere Yes same point it in release mode it only works on samsung. Can smne explain why?
@itssidhere Yes same point it in release mode it only works on samsung. Can smne explain why?
It seems a breaking change in the Facebook sdk on Android please check the documentation https://developers.facebook.com/docs/facebook-login/android/deprecating-webviews let me know if doing the changes in this documentation fix the problem
@darwin-morocho I tried that already but that doesn't seems to work
@darwin-morocho I tried that already but that doesn't seems to work
Please add your android manifest and your dart code.
Also add your MainActivty and your build.gradle
After check a similar issue on react native https://github.com/thebergamo/react-native-fbsdk-next/issues/64#issuecomment-870614017 it seems a problem with FlutterActivity so can you try this https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-557939158
@darwin-morocho
Manifest looks like this , though i have tried commenting customtab acitivity still no luck
<application android:name=".Application" android:icon="@mipmap/launcher_icon" android:roundIcon="@mipmap/ic_launcher_round" android:label="Mohalla" android:usesCleartextTraffic="true">
<activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize">
<!--
This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme).
-->
<!-- <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /> -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<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>
MainActivity
import android.content.Intent;
import io.flutter.embedding.engine.FlutterEngine;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity;
import java.nio.ByteBuffer;
import io.flutter.plugin.common.ActivityLifecycleListener;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterFragmentActivity {
private String sharedText;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
// GeneratedPluginRegistrant.registerWith(flutterEngine);
super.configureFlutterEngine(flutterEngine);
handleSendIntent(getIntent());
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "app.channel.shared.data").setMethodCallHandler(new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.contentEquals("getSharedText")) {
result.success(sharedText);
sharedText = null;
}
}
});
}
@Override
protected void onNewIntent(Intent intent) {
// Handle intent when app is resumed
super.onNewIntent(intent);
handleSendIntent(intent);
}
private void handleSendIntent(Intent intent){
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); // Handle text being sent
}
}
}
}
Build.gradle
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 29
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.cluxid.m"
minSdkVersion 23
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
}
flutter {
source '../..'
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.guava:guava:27.0.1-android'
implementation 'com.google.firebase:firebase-messaging:20.2.4'
}
apply plugin: 'com.google.gms.google-services'
Dart code
@override
Future<User> signInWithFacebook() async {
final result = await FacebookAuth.instance
.login(loginBehavior: LoginBehavior.nativeWithFallback);
switch (result.status) {
case LoginStatus.success:
AuthCredential credential =
FacebookAuthProvider.credential(result.accessToken.token);
await firebaseAuth.signInWithCredential(credential);
return firebaseAuth.currentUser;
break;
case LoginStatus.cancelled:
// TODO: Handle this case.
break;
case LoginStatus.failed:
// TODO: Handle this case.
break;
case LoginStatus.operationInProgress:
// TODO: Handle this case.
break;
}
return null;
}
Now it works fine for me I add a release hash key and my problem was that Facebook doesn't return the email parameter always for all users so it crashes on value["email"] adding ( value["email"] ?? value["id"]+"@facebook.com" ) solve my problem and it's working fine now I tested it on oppo Xiaomi and infinix and it's working hope this helps you
@darwin-morocho
Manifest looks like this , though i have tried commenting customtab acitivity still no luck
<application android:name=".Application" android:icon="@mipmap/launcher_icon" android:roundIcon="@mipmap/ic_launcher_round" android:label="Mohalla" android:usesCleartextTraffic="true"> <activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:windowSoftInputMode="adjustResize"> <!-- This keeps the window background of the activity showing until Flutter renders its first frame. It can be removed if there is no splash screen (such as the default splash screen defined in @style/LaunchTheme). --> <!-- <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /> --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity> <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>
MainActivity
import android.content.Intent; import io.flutter.embedding.engine.FlutterEngine; import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterFragmentActivity; import java.nio.ByteBuffer; import io.flutter.plugin.common.ActivityLifecycleListener; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterFragmentActivity { private String sharedText; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { // GeneratedPluginRegistrant.registerWith(flutterEngine); super.configureFlutterEngine(flutterEngine); handleSendIntent(getIntent()); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "app.channel.shared.data").setMethodCallHandler(new MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call.method.contentEquals("getSharedText")) { result.success(sharedText); sharedText = null; } } }); } @Override protected void onNewIntent(Intent intent) { // Handle intent when app is resumed super.onNewIntent(intent); handleSendIntent(intent); } private void handleSendIntent(Intent intent){ String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); // Handle text being sent } } } }
Build.gradle
def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { compileSdkVersion 29 lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.cluxid.m" minSdkVersion 23 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } buildTypes { release { minifyEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation 'com.google.guava:guava:27.0.1-android' implementation 'com.google.firebase:firebase-messaging:20.2.4' } apply plugin: 'com.google.gms.google-services'
Dart code
@override Future<User> signInWithFacebook() async { final result = await FacebookAuth.instance .login(loginBehavior: LoginBehavior.nativeWithFallback); switch (result.status) { case LoginStatus.success: AuthCredential credential = FacebookAuthProvider.credential(result.accessToken.token); await firebaseAuth.signInWithCredential(credential); return firebaseAuth.currentUser; break; case LoginStatus.cancelled: // TODO: Handle this case. break; case LoginStatus.failed: // TODO: Handle this case. break; case LoginStatus.operationInProgress: // TODO: Handle this case. break; } return null; }
You have 2 problems. First you have firebase messaging in your build.gradle that is not need it because that dependency is included in firebase_messagin. the second problem is your MainActivity extends of flutterfragmentactivity so you need to override the oncreate method an call to super.onCreate to keep the app activity state after resume
here one example https://pub.dev/packages/local_auth
@darwin-morocho onCreate method is deprecated isn't it?
@darwin-morocho onCreate method is deprecated isn't it?
no. is not deprecated
Now it works fine for me I add a release hash key and my problem was that Facebook doesn't return the email parameter always for all users so it crashes on value["email"] adding ( value["email"] ?? value["id"]+"@facebook.com" ) solve my problem and it's working fine now I tested it on oppo Xiaomi and infinix and it's working hope this helps you
Have you tested in device with Android 11?
maybe is deprecated but what you are using FlutterFragmentActivity?
@darwin-morocho for local auth
@darwin-morocho for local auth
if you are using java according to local auth documentation you need onCreate
Actually, their documentation was outdated I had a hard time with that too. Let me add onCreate and update you??
Actually, their documentation was outdated I had a hard time with that too. Let me add onCreate and update you??
yes use onCreate please or try to use FlutterActivity and test the. login with facebook if the login works with FlutterActivity you need to check your MainActivity and this is not a bug of this plugin and this issue should be closed
I added this line
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
I do agree with you that this is an issue of the underlying plugin but it should be kept open to discuss the workaround as more people encounter it they will create separate issues. Maybe we can come to a solution here.
I added this line
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
I do agree with you that this is an issue of the underlying plugin but it should be kept open to discuss the workaround as more people encounter it they will create separate issues. Maybe we can come to a solution here.
if the problem was fixed with onCreate method I will add this to the documentation
@darwin-morocho I tested it and it's the same. I am trying to pass null to the super method call of onCreate as suggested by the react-native solution. I will update you
@darwin-morocho still no luck
@darwin-morocho still no luck
Using the FlutterActivity instead of FlutterFragmentActivity?
@darwin-morocho still same
@darwin-morocho still same
I have tried to reproduce the issue installing local_auth and running the app in release mode with a HUAWEI with android 10 and everything is ok
please try this apk and let me know if the app crashes
Your app is working it seems
@darwin-morocho How did you manage to fix it?
nothing special just I have added the release key hash in the Facebook developers console and I have changed the app to production in the console . And also to generate this hash I used mac os
My app is signed by google play store so I had to manually convert the sha1 to base64 . It works on every device except mine. But your app works on mine too
My app is signed by google play store so I had to manually convert the sha1 to base64 . It works on every device except mine. But your app works on mine too
this app uses flutter Facebook auth https://play.google.com/store/apps/details?id=app.meedu.app can you install it and check if the problem persists
@darwin-morocho This app also works fine in my phone
@darwin-morocho This app also works fine in my phone
Google play console creates 2 sha1. Have you added both in your Facebook developers console?
@darwin-morocho yes
@darwin-morocho yes
in that case maybe your MainActivity is locking the Facebook sdk
Can you send me your MainActivity so that I can try to replicate it. I have also overriden Application java from mainfest can that be an issue as well
Can you send me your MainActivity so that I can try to replicate it. I have also overriden Application java from mainfest can that be an issue as well
just check the example folder of this repo
Still no luck
Still no luck
Have you tried creating a release keystore and creating the hash and next create a release apk using this keystore? also you need to add this hash in the facebook developers console
@darwin-morocho its working now with that method!
@darwin-morocho its working now with that method!
it seems a problem with your hash from google play console
Then why is it working on some devices but not all? Also can you tell me how you created the key from google play console sha1?
Hello, the plugin works well in debug mode but after trying it out on release mode I get this error.