darwin-morocho / flutter-facebook-auth

A flutter plugin to add login with facebook in your flutter app
193 stars 127 forks source link

MissingPluginException- No implementation found for method login on channel app.meedu/flutter_facebook_auth #253

Closed SalsabeelaHasan closed 1 year ago

SalsabeelaHasan commented 1 year ago

Describe the bug the code I wrote to implement the latest version (4.3.4) of the Facebook auth plugin in Android device is attached, it always goes to the "catch error section" and the error is:

I/flutter (10220): :: catch error :: MissingPluginException(No implementation found for method login on channel app.meedu/flutter_facebook_auth).

I can't understand the.. what the problem is and what should I do?

Environment

Add your flutter doctor -v

[✓] Flutter (Channel stable, 2.5.3, on macOS 12.2.1 21D62 darwin-x64,) • Flutter version 2.5.3 at /Applications/SDKs/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 18116933e7 (8 months ago), 2021-10-15 10:46:35 -0700 • Dart version 2.14.4

[!] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1) ✗ cmdline-tools component is missing Run path/to/sdkmanager --install "cmdline-tools;latest" See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run flutter doctor --android-licenses to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 13.2.1, Build version 13C100 • CocoaPods version 1.11.3

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

Add your pubspec.yaml

name: main_app description: x Main App publish_to: none version: 4.0.42+486

environment: sdk: ">=2.10.5 <3.0.0"

dependencies: flutter: sdk: flutter carousel_slider: ^4.1.1 flutter_statusbarcolor_ns: ^0.4.0 flutter_slidable: 0.6.0 flutter_animator: ^3.2.1 provider: ^6.0.2 firebase_core: 1.12.0 firebase_messaging: 11.2.6 google_mobile_ads: ^1.2.0 in_app_purchase: 0.5.2 google_fonts: 2.2.0 video_player: 2.2.17 youtube_player_flutter: ^8.0.0 photo_view: ^0.13.0 http: ^0.13.4 webview_flutter: ^3.0.4 flutter_widget_from_html: 0.8.3 overlay_support: ^1.2.1 timezone: ^0.8.0 uni_links: ^0.5.1

Utiles

flutter_app_badger: ^1.4.0 intl: ^0.17.0 device_info_plus: ^3.2.3 permission_handler: 8.3.0 simple_tooltip: ^1.0.0 store_redirect: ^2.0.1 flutter_hms_gms_availability: ^2.0.0 flutter_udid: ^2.0.0 quick_actions: 0.6.0+6 qr_flutter: ^4.0.0 flutter_facebook_auth: 4.2.1 twitter_login: ^4.0.1 google_sign_in: ^5.3.1 sign_in_with_apple: ^3.3.0 local_auth: ^1.1.11 cupertino_icons: ^1.0.4 flutter_typeahead: ^3.2.6 flutter_svg: ^1.0.3 shared_preferences: ^2.0.15 firebase_crashlytics: 2.5.0 firebase_analytics: 9.1.0 camera: ^0.9.6 wechat_assets_picker: 6.2.4 path_provider: ^2.0.10 flutter_share: ^2.0.0 in_app_review: ^2.0.4 tutorial_coach_mark: ^1.2.2 visibility_detector: ^0.2.2 package_info_plus: ^1.4.2 connectivity_plus: 2.2.0 url_launcher: ^6.1.2 app_tracking_transparency: ^2.0.2+4 flutter_inappwebview: ^5.4.3+7

Add your AndroidManifest.xml `<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x.main_app">

<application
    android:name="io.flutter.app.FlutterApplication"
    android:icon="@mipmap/ic_launcher"
    android:label=“x”
    android:usesCleartextTraffic="true">
    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:theme="@style/LaunchTheme"
        android:windowSoftInputMode="adjustResize"
        android:showWhenLocked="true"
        android:turnScreenOn="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <!-- App Links -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
        </intent-filter>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
    <!-- 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" />
    <service
        android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
        android:enabled="true" />
    <!-- Facebook Login configuration -->
    <meta-data
        android:name="com.facebook.sdk.ApplicationId"
        android:value="@string/facebook_app_id" />
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"></action>
      </intent-filter>
    </receiver>
    <activity
    android:name="com.yalantis.ucrop.UCropActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>    

</application>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission 

MainActivity

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ComponentName
import android.content.Context
import android.content.IntentFilter
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.AudioAttributes
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.NonNull
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.amazonaws.ClientConfiguration
import com.amazonaws.Protocol
import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.AWSCredentialsProvider
import com.amazonaws.auth.BasicSessionCredentials
import com.amazonaws.internal.StaticCredentialsProvider
import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener
import com.amazonaws.mobileconnectors.s3.transferutility.TransferState
import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility
import com.amazonaws.regions.Region
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3Client
import com.arabiaweather.weatherwidget.ui.WeatherWidget
import com.arabiaweather.weatherwidget.ui.WeatherWidgetFull
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.concurrent.TimeUnit

class MainActivity : FlutterFragmentActivity() {

    private val CHANNEL = “x.mainapp/aws"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onStart() {
        super.onStart()
    }

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {

        GeneratedPluginRegistrant.registerWith(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            // Note: this method is invoked on the main thread.

            Log.i("UPLOAD MEDIA", "UPLOAD MEDIA")
            when (call.method) {

                METHOD_UPLOAD_MEDIA -> {

                    val argsList = call.arguments as ArrayList<HashMap<String, Any>>
                    val args = argsList[0]
                    print(args)
                    val accessKey = args["accessKey"] as String
                    val secretKey = args["accessSecret"] as String
                    val sessionToken = args["sessionKey"] as String
                    val bucketName = args["bucket"] as String
                    val keyName = args["key"] as String
                    val endPoint = args["endPoint"] as String
                    val contentType = args["contentType"] as String
                    val filePath = args["path"] as String
                    val mediaFile = File(filePath)

                    if (contentType == "image/jpeg") {
                        val rotated = rotateImage(mediaFile)
                        if (!rotated) {
                            result.error("Image Rotation", "Cant rotate image", null)
                        }
                    }
                    val cred = AWSS3Credentials(accessKey, secretKey, bucketName, keyName, endPoint, sessionToken)
                    upLoadToS3(cred, mediaFile) { success, errorMessage ->
                        if (success) {
                            Log.i("UPLOAD MEDIA", "SUCCESS")
                            result.success(true)
                        } else {
                            Log.i("UPLOAD MEDIA ERROR ", "\"$errorMessage")
                            result.error("404", errorMessage, null)
                        }
                    }

                }
                METHOD_SEND_UPDATE_WEDGITS_BROADCAST -> sendUpdateWidgetsBroadcast()
            }
        }

    }

    private fun rotateImage(file: File): Boolean {
        var success: Boolean
        try {
            val exif = ExifInterface(file.path)
            val bitmap = BitmapFactory.decodeFile(file.path)
            val rotation: Int = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
            val rotationInDegrees: Int = exifToDegrees(rotation)
            val matrix = Matrix()
            if (rotation.toFloat() != 0f) {
                matrix.preRotate(rotationInDegrees.toFloat())
            }
            val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
            success = try {
                val stream: OutputStream = FileOutputStream(file)
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
                stream.flush()
                stream.close()
                true
            } catch (e: IOException) {
                e.printStackTrace()
                false
            }

        } catch (ex: IOException) {
            Log.i("Rotate  image", "Failed to get Exif data", ex)
            success = false
        }
        return success
    }

    private fun exifToDegrees(exifOrientation: Int): Int {
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270
        }
        return 0
    }

    private fun upLoadToS3(credentials: AWSS3Credentials, file: File, callBack: (Boolean, String?) -> Unit) {
        Log.i("START UPLOADING", "UPLOAD MEDIA")

        val amazonHelper = AmazonHelper()
        val transfer = amazonHelper.getTransferUtility(this,
                credentials.accessKey,
                credentials.secretAccessKey,
                credentials.sessionToken,
                credentials.endpoint)
        if (transfer != null) {
            val o = transfer.upload(credentials.bucket,
                    credentials.key,
                    file)
            o.setTransferListener(object : TransferListener {
                override fun onStateChanged(i: Int, transferState: TransferState) {
                    print(transferState)
                    if (transferState == TransferState.COMPLETED) {
                        Log.i("TransferState $transferState", "UPLOAD MEDIA")
                        callBack(true, null)
                    } else {
                        Log.i("TransferState $transferState", "UPLOAD MEDIA")
                    }
                }

                override fun onProgressChanged(i: Int, l: Long, l1: Long) {
                    Log.i("onProgressChanged", "UPLOAD MEDIA")
                    print("onProgressChanged")
                }

                override fun onError(i: Int, e: Exception) {
                    Log.i("ERROR ${e.message}", "UPLOAD MEDIA")
                    callBack(false, "onError code : $i ${e.message}")
                }
            })
        }

    }

    companion object{
        const val METHOD_UPLOAD_MEDIA = "uploadMedia"
        const val METHOD_SEND_UPDATE_WEDGITS_BROADCAST = "update_widgets"
        const val IS_COMMING_FROM_WIDGET = "is_comming_from_widget"
    }
}

class AmazonHelper {
    private fun getS3Client(accessKey: String, secretKey: String, token: String, endPoint: String): AmazonS3Client {
        val credentials: AWSCredentials = BasicSessionCredentials(accessKey, secretKey, token)
        val provider: AWSCredentialsProvider = StaticCredentialsProvider(credentials)
        val clientConfig = ClientConfiguration()
        clientConfig.protocol = Protocol.HTTPS
        clientConfig.connectionTimeout = 90000
        clientConfig.socketTimeout = 90000
        val s3Client = AmazonS3Client(provider, clientConfig)
        s3Client.endpoint = endPoint
        s3Client.setRegion(Region.getRegion(Regions.EU_WEST_1))
        return s3Client
    }

    fun getTransferUtility(context: Context, accessKey: String,
                           secretKey: String, token: String, endPoint: String): TransferUtility? {
        return TransferUtility.builder()
                .s3Client(getS3Client(accessKey, secretKey, token, endPoint))
                .context(context.applicationContext).build()
    }
}

class AWSS3Credentials {
    var accessKey: String = ""
    var secretAccessKey: String = ""
    var sessionToken: String = ""
    var bucket: String = ""
    var key: String = ""
    var endpoint: String = ""
    constructor(accessKey: String, secretAccessKey: String, bucket: String, key: String, endpoint: String, sessionToken: String) {
        this.accessKey = accessKey
        this.secretAccessKey = secretAccessKey
        this.bucket = bucket
        this.key = key
        this.endpoint = endpoint
        this.sessionToken = sessionToken
    }
}

Add your /app/res/values/strings.xml

string name="facebook_app_id">** string name="fb_login_protocol_scheme">fb**

To Reproduce

 try {
      FacebookAuth _instance = FacebookAuth.instance;
      if (Platform.isAndroid) {
        result = await _instance.login(
          loginBehavior: LoginBehavior.dialogOnly,
          permissions: ['email', 'public_profile'],
        ).catchError((error){
          print(":: catchError :: ${error}");
        });
      }

Expected behaviour enter the Facebook UI interface to complete the login process.

Screenshots there is nothing to provide.

darwin-morocho commented 1 year ago

@SalsabeelaHasan please follow the issue template. If you don't do it I will close this

SalsabeelaHasan commented 1 year ago

@darwin-morocho done, check now!

darwin-morocho commented 1 year ago

android:name="com.facebook.sdk.ApplicationId"

@SalsabeelaHasan your AndroidManifest is incomplete

SalsabeelaHasan commented 1 year ago

@darwin-morocho these are the facebook values in AndroidManifest.xml , I used it previously in the old version and everything runs fine, what is the missing part? <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />

darwin-morocho commented 1 year ago

@darwin-morocho these are the facebook values in AndroidManifest.xml , I used it previously in the old version and everything runs fine, what is the missing part? <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />

@SalsabeelaHasan I will close this because you don't provide me the enough info

SalsabeelaHasan commented 1 year ago

@darwin-morocho Wow! This is so terrible, u don't help me by doing that! Please explain what u mean and what u want or answer my questions, this is unacceptable!

In previous comment I mentioned what I have and all is good, but In latest version is not.

darwin-morocho commented 1 year ago

@darwin-morocho Wow! This is so terrible, u don't help me by doing that! Please explain what u mean and what u want or answer my questions, this is unacceptable!

In previous comment I mentioned what I have and all is good, but In latest version is not.

@SalsabeelaHasan all info provided by you is incomplete. Example your pubspec.yaml, MainActivity and AndroidManifest are incomplete. Without that info I am not able to find the problem. And I'm really tired about issues similar to this without the enough info.

SalsabeelaHasan commented 1 year ago

@darwin-morocho, thanks for your effort, but you have to be patient before closing issues, to help us know what is required.. anyway, the information has been modified and now it is complete as you explained the last thing.

darwin-morocho commented 1 year ago

@SalsabeelaHasan your android manifest is wrong.

check https://facebook.meedu.app/docs/4.x.x/android