【问题标题】:Is it possible to recieve data only notifications in the system tray?是否可以在系统托盘中接收仅数据通知?
【发布时间】:2020-06-30 15:35:23
【问题描述】:

我从 CloudFunction 发送带有以下负载的通知

    const payload: admin.messaging.MessagingPayload = {
        // notification: {
        //     title: `${translator['messageTitle' as keyof typeof translator]} ${group.displayName}`,
        //     body: `${sender.displayName} ${translator[type as keyof typeof translator]}`,
        //     clickAction: 'FLUTTER_NOTIFICATION_CLICK',
        // },
        data: {
            title: `${translator['messageTitle' as keyof typeof translator]} ${group.displayName}`,
            body: `${sender.displayName} ${translator[type as keyof typeof translator]}`,
            clickAction: 'FLUTTER_NOTIFICATION_CLICK',
            senderId: sender.id,
            senderDisplayName: sender.displayName,
            groupId: group.id,
            type: 'groupMessage',
            messageType: type,
            sentAt: new Date().toISOString(),
        }
    }

为了让 OnBackgroundMessage 工作,我需要从我的负载中删除通知部分。但这也意味着它们将不再出现在我的系统托盘中。如何在系统托盘中显示它们?是否涉及制作通知渠道?

我添加了 Application.kt

package HERE_I_HAVE_MY_PACKAGE_NAME

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

public class Application: FlutterApplication(), PluginRegistrantCallback {
  override fun onCreate() {
    super.onCreate()
    FlutterFirebaseMessagingService.setPluginRegistrant(this)
  }

  override fun registerWith(registry: PluginRegistry) {
    FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
  }
}

还有 FirebaseCloudMessagingPluginRegistrant.kt

package HERE_I_HAVE_MY_PACKAGE_NAME

import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

class FirebaseCloudMessagingPluginRegistrant {
  companion object {
    fun registerWith(registry: PluginRegistry) {
      if (alreadyRegisteredWith(registry)) {
        return;
      }
      FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
    }

    fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
      val key = FirebaseCloudMessagingPluginRegistrant::class.java.name
      if (registry.hasPlugin(key)) {
        return true
      }
      registry.registrarFor(key)
      return false
    }
  }
}

这是我的 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company_name.app_name">
    <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.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>

【问题讨论】:

    标签: flutter dart firebase-cloud-messaging


    【解决方案1】:

    我将flutter_local_notifications 插件与 FCM 一起使用,一旦您拥有后台消息处理程序,处理数据并调用显示通知的函数,插件将为您创建通知。

    一个例子:

    这应该在某种辅助类中:

    
      static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
        if (message.containsKey('data')) {
          final body = message['data']['message'];
          final title = message['data']['title'];
          final notifications = FlutterLocalNotificationsPlugin();
          showOngoingNotification(notifications,title, body);
        }
      }
    
      static NotificationDetails get _dets {
        final androidChannelSpecifics = AndroidNotificationDetails(
          'channel id',
          'channel name',
          'channel description',
          importance: Importance.Max,
          priority: Priority.High,
          ongoing: false,
          autoCancel: true,
        );
        final iOSChannelSpecifics = IOSNotificationDetails();
        return NotificationDetails(androidChannelSpecifics, iOSChannelSpecifics);
      }
    
      static Future showOngoingNotification(FlutterLocalNotificationsPluginnotifications,String title, String body) async 
        var id = 0;
        var payload = 'somepayload';
        NotificationDetails dets = _dets;
        notifications.show(id, title, body, dets, payload: payload)
      }
    

    这是在 main.dart 中:

    final notifications = FlutterLocalNotificationsPlugin();
    
      void InitializeLocalNotifs(){
        final settingsAndroid = AndroidInitializationSettings('app_icon'); //make sure this is the same name as your icon
        final settingsIOS = IOSInitializationSettings(
            onDidReceiveLocalNotification: (id, title, body, payload) =>
                onSelectNotification(payload)); //if you want to get permissions at a different time set everything to false and ask for them later
    
        notifications.initialize(
            InitializationSettings(settingsAndroid, settingsIOS),
            onSelectNotification: onSelectNotification);
      }
    
     Future onSelectNotification(String payload) async {
        //do whatever with payload, I usually send the page to push in the payload and push it like this
       // await Navigator.pushNamed(context, payload);
      }
    
     @override
      void initState() {
        InitializeLocalNotifs();
        InitializeFCM();
        super.initState();
      }
    

    【讨论】:

    • IOS也能用吗?我读到 onBackgroundMessage 在 IOS 上不起作用。
    • 我还没有测试过,但是 IOS 应该在 fcm.configure 设置中捕获 onLaunchonResume 回调,你可以从那里调用显示通知,它会工作相同
    • 但我希望在应用关闭时显示通知。仅当您点击通知时才会触发 onResume 和 onLaunch。
    • 是的,看起来你是对的,最好的选择似乎是原生代码实现
    • 你能支持这个问题吗?我很想得到一些关注。
    【解决方案2】:

    我最终发送了 2 个有效的通知。一个带有通知和数据对象,另一个带有数据对象。在我的前端,我检查它是否是仅数据通知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 2020-05-14
      • 2018-12-12
      相关资源
      最近更新 更多