Flutter FCM 通知点击不会调用 `getInitialMessage()`

问题描述 投票:0回答:1

我一直在开发一个 Flutter 应用程序,它需要支持点击通知并将您带到应用程序中的某个位置。但是,当点击通知时,它不会调用我创建的任何回调。它只是正常打开应用程序到主页。我从 Node.js 后端发送通知,并使用

firebase-admin
npm 包发送通知。

我发送这样的通知:

/**
 * Trigger sending a notification
 */
const sendNotification = async ({
    title,
    body,
    data,
    notificationType,
    topic,
    sendTo,
    mediaUrl,
}) => {
    let tokens = [];
    if (sendTo) {
        console.log(`sending targeted notitification to: ${sendTo}`);
        tokens = await getUserFCMTokens(sendTo);
    }
    const notification = {
        data: {
            ...data,
            notificationType: NOTIFICATION_TYPE[notificationType].toString(),
            title: title,
            body: body,
        },
        ...(topic && { topic: topic }),
        ...(tokens.length > 0 && { tokens }),
        apns: {
            headers: {
                'apns-priority': '5',
            },
            payload: {
                aps: {
                    contentAvailable: true,
                },
            },
        },
        android: {
            priority: 'high',
            notification: {
                click_action: 'FLUTTER_NOTIFICATION_CLICK',
                priority: 'high',
                sound: 'default',
            },
        },
    };

    console.log(notification);

    try {
        if (tokens.length > 0) {
            // Send to multiple devices
            const response = await admin
                .messaging()
                .sendEachForMulticast(notification);
            console.log(
                `Successfully sent message to ${response.successCount} devices`
            );
            if (response.failureCount > 0) {
                console.log(
                    `Failed to send message to ${response.failureCount} devices`
                );
                response.responses.forEach((resp, idx) => {
                    if (!resp.success) {
                        console.log(
                            `Failed to send to token at index ${idx}: ${resp.error}`
                        );
                    }
                });
            }
        } else if (topic) {
            // Send to topic
            const response = await admin.messaging().send(notification);
            console.log('Successfully sent message:', response);
        } else {
            console.log('No valid recipients (tokens or topic) specified');
        }
    } catch (error) {
        console.error('Error sending notification:', error);
    }
};

打印出来的通知可能看起来像这样:

{
  data: {
    group: '6716a89768497667e665546c',
    media: '',
    message: '6716a8d868497667e66554a4',
    notificationType: '3',
    title: 'title goes here',
    body: '@zh22: Message goes here '
  },
  topic: 'group_6716a89768497667e665546c',
  apns: { headers: { 'apns-priority': '5' }, payload: { aps: [Object] } },
  android: {
    priority: 'high',
    notification: {
      click_action: 'FLUTTER_NOTIFICATION_CLICK',
      priority: 'high',
      sound: 'default'
    }
  }
}

然后,在客户端的

main.dart
内部,我初始化 Firebase 后台处理程序,并设置
getInitialMessage
回调以在单击通知时打开应用程序中的某个屏幕。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  await AppData.initiate();

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print("onMessage: $message");
  });

  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print("onMessageOpenedApp: $message");
    NotificationHandler.handleNotificationOnTap(message);
  });

  FirebaseMessaging.onBackgroundMessage(_onBackgroundMessage);

  FirebaseMessaging.instance
      .getInitialMessage()
      .then(NotificationHandler.handleNotificationOnTap);

  runApp(
    ShowCaseWidget(builder: (context) {
      return const MyApp();
    }),
  );
}

@pragma("vm:entry-point")
Future<void> _onBackgroundMessage(RemoteMessage message) async {
  print("onBackgroundMessage: $message");
  print("data: ${message.data}");

  final NotificationRepository notificationRepository =
      NotificationRepositoryImpl();

  final FlutterLocalNotificationsPlugin localNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  // show notification
  const AndroidNotificationDetails androidNotificationDetails =
      AndroidNotificationDetails(
          "basecamp_notifications", "Basecamp Notifications",
          importance: Importance.max,
          priority: Priority.high,
          ticker: 'ticker');

  const DarwinNotificationDetails iosNotificationDetails =
      DarwinNotificationDetails(
          presentAlert: true,
          presentSound: true,
          interruptionLevel: InterruptionLevel.active);

  int notificationId = 1;

  const NotificationDetails platformSpecifics = NotificationDetails(
      android: androidNotificationDetails, iOS: iosNotificationDetails);

  await localNotificationsPlugin.initialize(
    const InitializationSettings(
      android: AndroidInitializationSettings("@mipmap/ic_launcher"),
      iOS: DarwinInitializationSettings(),
    ),
    onDidReceiveNotificationResponse: (NotificationResponse details) {
  
      if (details.payload != null) {
        final data = json.decode(details.payload!);
        final message = RemoteMessage(data: Map<String, String>.from(data));
        NotificationHandler.handleNotificationOnTap(message);
      }
    },
  );

    final title = message.data["title"];
    final body = message.data["body"];

    await localNotificationsPlugin.show(
        notificationId, title, body, platformSpecifics,
        payload: message.data.toString());
  
}

@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
  print(notificationResponse);
  // NotificationHandler.handleNotificationOnTap();
}

我尝试将

NotificationHandler.handleNotificationTap()
设置为本地通知插件的
onDidReceiveNotificationResponse
属性以及
FirebaseMessaging.onBackgroundHandler
的回调。当我点击物理设备上收到的通知时,两者都不会被调用。

当我从后端收到通知时,应用程序端的输出如下所示:

flutter: onBackgroundMessage: Instance of 'RemoteMessage'
flutter: data: {body: @zh22: Message goes here, message: 6716a8d868497667e66554a4, title: @title goes here, group: 6716a89768497667e665546c, notificationType: 3, media: }
flutter: remoteMessage: null

请注意,收到通知时也会打印

remoteMessage: null
,我认为这很奇怪。

最后,当我点击通知时,没有打印任何内容,让我相信

getInitialMessage
没有在正确的时间被调用,并且
onMessageOpenedApp
似乎根本没有被调用。我在
NotificationHandler.handleNotificationTap()
内部还有一条打印语句,在整个过程中从未打印过该语句,这让我相信该函数从未被输入过。

目前在 iOS 上运行。确保包含推送通知功能和 Xcode。

FirebaseAppDelegateProxyEnabled
设置为 NO。 为什么当我点击通知时这些回调都不起作用?

ios node.js flutter firebase firebase-cloud-messaging
1个回答
0
投票
Bro try this:-
import 'dart:developer';

import 'package:firebase_messaging/firebase_messaging.dart';

Future<void> BackgroundHandler(RemoteMessage remotemessage) async {
  log("Message Received ${remotemessage.notification!.title}");
}

class NotificationService {
  Future<void> initialize() async {
    NotificationSettings notificationSettings =
        await FirebaseMessaging.instance.requestPermission();
    if (notificationSettings.authorizationStatus ==
        AuthorizationStatus.authorized) {
      FirebaseMessaging.onBackgroundMessage(BackgroundHandler);
      FirebaseMessaging.onMessage.listen((message) {
        log("Message Received ${message.notification!.title.toString()}");
      });
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.