简体   繁体   中英

FCM notifications delivering only with the app opened (iOS Flutter)

In this project, if one given user do something, the others receive a push from Firebase Messaging. In android it is working fine, but in iOS the message arrives on the users phones only if the app is opened. If in background, when you app again the app, it shows the notification

Things I already did:

  • 1 Create a key in developers.apple and apply it within firebase
  • 2 feed my project with googleservices.plist
  • 3 turn on Push Notifications and Background Modes, and enable Background fetch and Remote notifications under Background Modes.
  • 4 Added this code in my info.plist:
<key>FirebaseScreenReportingEnabled</key>
<true/>
<key>FirebaseAppDelegateProxyEnabled</key>
<true/>

And in AppDelegate.swift, I already tried this two codes: 1 (from FirebaseMessaging documentation)

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

and 2

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    if #available(iOS 10.0, *) {
      // For iOS 10 display notification (sent via APNS)
      UNUserNotificationCenter.current().delegate = self

      let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
      UNUserNotificationCenter.current().requestAuthorization(
        options: authOptions,
        completionHandler: {_, _ in })
    } else {
      let settings: UIUserNotificationSettings =
      UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
      application.registerUserNotificationSettings(settings)
    }

    application.registerForRemoteNotifications()
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}


The second one arrives the messages with the app opened, with the first one it don't arrive at all. I'm using FlutterLocalNotifications to treat when the app is opened, and might be some conflicts between LocalNotifications and FCM (I'm not sure, just thinking).

How could I handle that to receive background notifications too?:

There are something I miss? The following code is my PushNotifications.dart

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:app_md/providers/auth_provider.dart';
import 'package:app_md/providers/notification_plugin.dart';
import 'package:app_md/utils/app_routes.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

class PushNotificationsManager {

  PushNotificationsManager._();

  factory PushNotificationsManager() => _instance;

  static final PushNotificationsManager _instance = PushNotificationsManager
      ._();

  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  final NotificationPlugin _notificationPlugin = NotificationPlugin();



  Future<void> init() async {
    if (Platform.isIOS) {
      _firebaseMessaging.requestNotificationPermissions(
          IosNotificationSettings());
    }
    _firebaseMessaging.configure(
      // Called when the app is in the foreground and we receive a push notif.
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: ${message}");
        print(message['notification']['body']);
        _notificationPlugin.showNotification(
            title: 's',
            content: message['notification']['body']
        );
        //sendNotification();
      },
      // Called when the app has been closed completely and its opened
      // from the notification directly
      onBackgroundMessage: Platform.isAndroid ? myBackgroundMessageHandler:null,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");

       // _navigateToItemDetail(message);
      },
      // Called when the app is in the background and its opened from the notif
      onResume: (Map<String, dynamic> message) async {
        print("onMessage: ${message}");
      },
    );

  }

  subscribeToTopicNotification() async {
    await _firebaseMessaging.subscribeToTopic("MYTOPIC");
  }

  unsubscribeToTopicNotification() async {
    await _firebaseMessaging.unsubscribeFromTopic("MYTOPIC");
  }

  Future sendNotification(String body, String title, bool isAdm) async {
    !isAdm ? subscribeToTopicNotification() : null;
    final String url = 'https://fcm.googleapis.com/fcm/send';
    var data;
    data =
    '{"notification": {"body": "${body}", "title": "${title}", "content_available": "true"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK"}, "to": "/topics/MYTOPIC"}';
    final response = await http.post(
        url,
        headers: <String, String>{
          "Content-Type": "application/json",
          "Keep-Alive": "timeout=5",
          "Authorization": "MYKEY"
        },
        body: data
    );

    print(response.body);
  }
}

It seams that you are sending a data message rather than a notification message. The behavior that you described (notification is sent when you reopen the app) is the behavior of a data message. More info on that in the docs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM