当前位置: 首页 > 知识库问答 >
问题:

如何正确注册FCM插件

龙承德
2023-03-14

我正在使用https://pub.dev/packages/firebase_messagingv6。0.16和颤振v1。17.5

[√] Flutter (Channel stable, v1.17.5, on Microsoft Windows [Version 10.0.18362.900], locale en-US)
 
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[√] Android Studio (version 4.0)
[√] VS Code (version 1.47.0)

我正在尝试调用myBackgroundMessageHandler中的一个插件,它的代码是AppAvailability。启动应用程序('com.companyname.appname')

class CloudMessagingService extends NotificationService {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  void configure() {
    if (Platform.isIOS) _firebaseMessaging.requestNotificationPermissions(IosNotificationSettings());

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        if (isDataNotification(message)) return;
        print('onMessage');
      },
      onLaunch: (Map<String, dynamic> message) async {
        if (isDataNotification(message)) return;
        print('onLaunch');
      },
      onResume: (Map<String, dynamic> message) async {
        if (isDataNotification(message)) return;
        print('onResume');
      },
      onBackgroundMessage: myBackgroundMessageHandler,
    );
  }

  static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
    print('on background message');
    AppAvailability.launchApp('com.companyname.appname'); // it will throw an error when it tries to call the method channel in the app availability plugin
    return message;
  }

但我得到以下错误

E/flutter (28000): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method launchApp on channel com.pichillilorenzo/flutter_appavailability)
E/flutter (28000): #0      MethodChannel._invokeMethod 
package:flutter/…/services/platform_channel.dart:154
E/flutter (28000): <asynchronous suspension>
E/flutter (28000): #1      MethodChannel.invokeMethod 
package:flutter/…/services/platform_channel.dart:329
E/flutter (28000): #2      AppAvailability.launchApp 
package:flutter_appavailability/flutter_appavailability.dart:95
E/flutter (28000): #3      CloudMessagingService.myBackgroundMessageHandler 
package:moto_picto/…/firebase/cloud_messaging_service.dart:43
E/flutter (28000): #4      _fcmSetupBackgroundChannel.<anonymous closure> 
package:firebase_messaging/firebase_messaging.dart:38
E/flutter (28000): #5      MethodChannel._handleAsMethodCall 
package:flutter/…/services/platform_channel.dart:409
E/flutter (28000): #6      MethodChannel.setMethodCallHandler.<anonymous closure> 
package:flutter/…/services/platform_channel.dart:377
E/flutter (28000): #7      _DefaultBinaryMessenger.handlePlatformMessage 
package:flutter/…/services/binding.dart:199
E/flutter (28000): #8      _invoke3.<anonymous closure>  (dart:ui/hooks.dart:290:15)
E/flutter (28000): #9      _rootRun  (dart:async/zone.dart:1184:13)
E/flutter (28000): #10     _CustomZone.run  (dart:async/zone.dart:1077:19)
E/flutter (28000): #11     _CustomZone.runGuarded  (dart:async/zone.dart:979:7)
E/flutter (28000): #12     _invoke3  (dart:ui/hooks.dart:289:10)
E/flutter (28000): #13     _dispatchPlatformMessage  (dart:ui/hooks.dart:164:5)

插件在应用程序范围内没有任何问题。这是发生在我尝试的每一个插件!

所以我认为问题在于FCM所做的隔离并没有用颤振引擎来包装,我从这篇文章中了解到了这一点。

https://github.com/flutter/flutter/issues/13937#issuecomment-656239596

但是您需要创建一个自定义应用程序类,该类与插件的后台视图的初始化挂钩。

我确实按照指示更改了我的申请。kt至以下各项:

package com.companyname.appname
    
import `in`.jvapps.system_alert_window.SystemAlertWindowPlugin
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import io.flutter.view.FlutterMain
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

import android.os.Build
import android.app.NotificationManager
import android.app.NotificationChannel

public class Application: FlutterApplication(), PluginRegistrantCallback {

   override fun onCreate() {
     super.onCreate();
     FlutterFirebaseMessagingService.setPluginRegistrant(this);
     createNotificationChannels();
     SystemAlertWindowPlugin.setPluginRegistrant(this);
     FlutterMain.startInitialization(this);
   }

   override fun registerWith(registry: PluginRegistry) {
    if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
      FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    }
    if (!registry!!.hasPlugin("in.jvapps.system_alert_window")) {
      SystemAlertWindowPlugin.registerWith(registry!!.registrarFor("in.jvapps.system_alert_window"));
    }
   }

   fun createNotificationChannels() {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = "groupChannel";
        val descriptionText = "This is the group channel";
        val importance = NotificationManager.IMPORTANCE_HIGH;
        val mChannel = NotificationChannel("59054", name, importance);
        mChannel.description = descriptionText;
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager;
        notificationManager.createNotificationChannel(mChannel);
    }
  }
}

还有我的主要活动。kt

package com.companyname.appname

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }
}

还有我的机器人。xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.companyname.appname">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE " />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!-- 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=".Application"
        android:label="App Name"
        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">
            <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>
        </activity>
        <activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
        <!-- 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.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id"/>  
    </application>
</manifest>

这些通知似乎正确地显示为提示通知,我可以调用我的BackgroundMessageHandler并执行代码,只是我不能对myBackgroundMessageHandler中的任何插件做任何事情。我是否正确地实施了它?

它将始终在这一行AppAvailability上抛出错误。启动应用程序('com.companyname.appname') myBackgroundMessageHandler中的code>,因为如果插件未注册,则隔离方法无法调用方法通道。

我还查看了这篇github帖子

类似的问题

但是我的申请。kt是这样设置的吗

我试着把颤振清理干净-

缺少插件异常(在通道dexterous.com/flutter/local_notifications上没有找到方法显示的实现)

编辑:当我使用DeviceApp插件时,同样的事情也会发生。我换了

AppAvailability.launchApp('com.companyname.appname');

具有

 DeviceApps.openApp('com.companyname.appname');

因此,我使用应用程序方法向registerWith添加了以下两行。kt,它似乎扭转了缺少的插件异常

if (!registry!!.hasPlugin("fr.g123k.deviceapps")) {
  DeviceAppsPlugin.registerWith(registry!!.registrarFor("fr.g123k.deviceapps"));
}

但错误变为

E/flutter (25583): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference, null)
E/flutter (25583): #0      StandardMethodCodec.decodeEnvelope 
package:flutter/…/services/message_codecs.dart:569
E/flutter (25583): #1      MethodChannel._invokeMethod 
package:flutter/…/services/platform_channel.dart:156
E/flutter (25583): <asynchronous suspension>
E/flutter (25583): #2      MethodChannel.invokeMethod 
package:flutter/…/services/platform_channel.dart:329
E/flutter (25583): #3      DeviceApps.openApp 
package:device_apps/device_apps.dart:81
E/flutter (25583): #4      CloudMessagingService.myBackgroundMessageHandler 
package:moto_picto/…/firebase/cloud_messaging_service.dart:73
E/flutter (25583): #5      _fcmSetupBackgroundChannel.<anonymous closure> 
package:firebase_messaging/firebase_messaging.dart:38
E/flutter (25583): #6      MethodChannel._handleAsMethodCall 
package:flutter/…/services/platform_channel.dart:409
E/flutter (25583): #7      MethodChannel.setMethodCallHandler.<anonymous closure> 
package:flutter/…/services/platform_channel.dart:377
E/flutter (25583): #8      _DefaultBinaryMessenger.handlePlatformMessage 
package:flutter/…/services/binding.dart:199
E/flutter (25583): #9      _invoke3.<anonymous closure>  (dart:ui/hooks.dart:290:15)
E/flutter (25583): #10     _rootRun  (dart:async/zone.dart:1184:13)
E/flutter (25583): #11     _CustomZone.run  (dart:async/zone.dart:1077:19)
E/flutter (25583): #12     _CustomZone.runGuarded  (dart:async/zone.dart:979:7)
E/flutter (25583): #13     _invoke3  (dart:ui/hooks.dart:289:10)
E/flutter (25583): #14     _dispatchPlatformMessage  (dart:ui/hooks.dart:164:5)

所以现在它不再说插件丢失,而是说平台异常(错误,尝试调用虚拟方法android.content.pm.PackageManagerandroid.app.ctivity.getPackageManager()

编辑2:

我刚刚注意到最近的错误https://github.com/g123k/flutter_plugin_device_apps/issues/31可能是插件本身的一部分。看看不同的插件现在是否可以工作

我希望我提供了足够的信息,请让我知道是否需要更多的信息,或者如果问题需要修改。我可以在几分钟内回复。

共有1个答案

傅茂实
2023-03-14

原来这只是我第一次编辑后的插件!只是用共享的首选项尝试了一下,效果很好!

MY_PACKAGE_NAME

import `in`.jvapps.system_alert_window.SystemAlertWindowPlugin
import fr.g123k.deviceapps.DeviceAppsPlugin

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
import io.flutter.view.FlutterMain
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin

import android.os.Build
import android.app.NotificationManager
import android.app.NotificationChannel

public class Application: FlutterApplication(), PluginRegistrantCallback {

   override fun onCreate() {
     super.onCreate();
     FlutterFirebaseMessagingService.setPluginRegistrant(this);
     SystemAlertWindowPlugin.setPluginRegistrant(this);
     createNotificationChannels();
     FlutterMain.startInitialization(this);
   }

   override fun registerWith(registry: PluginRegistry?) {
    if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
      FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    }
    if (!registry!!.hasPlugin("in.jvapps.system_alert_window")) {
      SystemAlertWindowPlugin.registerWith(registry!!.registrarFor("in.jvapps.system_alert_window"));
    }
    if (!registry!!.hasPlugin("plugins.flutter.io.shared_preferences")) {
      SharedPreferencesPlugin.registerWith(registry!!.registrarFor("plugins.flutter.io.shared_preferences"));
    }
   }

   fun createNotificationChannels() {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = "groupChannel";
        val descriptionText = "This is the group channel";
        val importance = NotificationManager.IMPORTANCE_HIGH;
        val mChannel = NotificationChannel("59054", name, importance);
        mChannel.description = descriptionText;
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager;
        notificationManager.createNotificationChannel(mChannel);
    }
  }
}
 类似资料:
  • 我对在我的应用程序中实施Firebase云消息传递有一些疑问。 我的应用程序类似于whatsapp和facebook messenger。现在,每次有人登录时,我都会注册令牌并将其与用户关联。因此,如果有人想与用户聊天,应用程序会在数据库中搜索用户ID,我在那里找到了他的令牌。 我可以注册设备令牌,但我不确定何时应该注册。 在我的聊天中,用户通过邮件/密码注册进行注册,并且用户可以登录其他设备。

  • 我试图使用FCM进行推送通知,但出现了一个错误 {“多播id”:543826995043253,“成功”:0,“失败”:1,“规范id”:0,“结果”:[{“错误”:“无效注册”}] 我的代码是:

  • 问题内容: 我获得了用于Web推送的Firebase Cloud Messaging注册令牌。然后,我将此邮件发送到服务器以保存在数据库中,以供以后推送。但是,如何验证此令牌有效或伪造的? 我已经尝试过了,但是我认为这是针对Auth令牌而不是针对Web推送的。 其他人可以将随机伪造令牌的请求发送到我的服务器。我想防止这种情况,然后再保存到数据库中。 编辑:已解决,我编写了一个简单的类来使用FCM快

  • 插件要生效, 还需要向Yaf_Dispatcher注册, 那么一般的插件的注册都会放在Bootstra中进行. 一个注册插件的例子如下: 例 7.2. 注册插件 <?php class Bootstrap extends Yaf_Bootstrap_Abstract{ public function _initPlugin(Yaf_Dispatcher $dispatcher) { $user

  • 我试图发出授权请求,但收到错误: 重定向URI未正确注册到DocuSign 这是我正在使用的URL: https://account-d.docusign.com/oauth/auth?response_type=code 这是我注册的重定向URI,与上面的URL匹配: 这是错误: 客户端id与integrator密钥匹配。 有什么指点吗?

  • 我用FCM发送推送通知,我的代码在Chrome上运行得很好,但在Firefox上却很困难。我得到了这样的回应 我的完整API请求如下所示 https://fcm.googleapis.com/fcm/send 标题 TTL:60 用户代理:Fiddler 主持人:fcm。古格里皮斯。通用域名格式 授权:密钥=aBCABC-aBCABC 内容类型:应用程序/json 内容-长度:250 身体 {“t