FCM通知消息不支持largeIcon
或bigPicture
。
所以在我使用的背景中
FCM数据消息
对于数据消息,始终会调用onMessageReceived(message)
方法,因此我使用了message.getData()
方法并创建了自定义通知
我从here获得了帮助。
这是我的firebase服务
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
* Created by wajdan on 10/3/17.
*/
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "wajdanFCM";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG,"onMessageReceived "+" wajdanFCM");
Object obj = remoteMessage.getData().get("id");
if (obj != null) {
sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"),,remoteMessage.getData().get("image"));
int id = Integer.valueOf(obj.toString());
}
}
private void sendNotification(String messageTitle, String messageBody, Bitmap image) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);
long[] pattern = {500,500,500,500,500};
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(getApplicationContext().getApplicationInfo().icon)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setLargeIcon(image)
.setVibrate(pattern)
.setLights(Color.BLUE,1,1)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(15 /* ID of notification */, notificationBuilder.build());
}
}
我如何接收远程通知,我可以实现上述针对iOS的方案(使用数据消息并生成自定义通知)/远程添加图像(通过通知消息)。到目前为止,我已成功收到远程通知fcm Android和iOS的消息(在前台和后台),但无法接收数据消息(前景和背景)。这是我的两个有效负载
{
"notification": {
"title": "Anzen",
"body": "from postman Notification",
"icon": "http://avatarbox.net/avatars/img32/test_card_avatar_picture_88303.jpg",
"tag":14
},
"registration_ids": ["android token id...","iOS token id..."]
}
{
"priority":"high",
"content-available":1,
"data":{
"title":"Anzen",
"body":"from postman DATA",
"id":1,
"image": "http://avatarbox.net/avatars/img32/test_card_avatar_picture_88303.jpg"
},
"registration_ids": ["android token id...","iOS token id..."
]
}
这是我的app delegate
//
// AppDelegate.swift
// wajdanMQTT
//
// Created by wajdanAli on 7/17/17.
// Copyright © 2017 wajdanAli. All rights reserved.
//
import UIKit
import UserNotifications
import Firebase
import FirebaseMessaging
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
// if let messageID = userInfo[gcmMessageIDKey]
// {
// print("Message ID: (messageID)")
//}
// Print full message.
print(userInfo)
AppDelegate.fcmmessage = "first apn func"
AppDelegate.backgrndShared(num:4)
// Change this to your preferred presentation option
completionHandler([])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
// if let messageID = userInfo[gcmMessageIDKey] {
// print("Message ID: (messageID)")
// }
// Print full message.
print(userInfo)
AppDelegate.fcmmessage = "second apn func"
AppDelegate.backgrndShared(num:5)
completionHandler()
}
}
extension AppDelegate : MessagingDelegate
{
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String)
{
print("Firebase registration token changed : \(fcmToken)")
}
// [START refresh_token]
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
AppDelegate.backgrndShared(num:10)
}
// [END ios_10_data_message]
func application(received remoteMessage: MessagingRemoteMessage)
{
AppDelegate.backgrndShared(num:12)
}
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static var devicetokenString:String?
static var fcmdevicetokenString:String?
static var fcmmessage:String?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// iOS 10 support
if #available(iOS 11, *)
{
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
application.registerForRemoteNotifications()
}
// iOS 10 support
if #available(iOS 10, *)
{
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
application.registerForRemoteNotifications()
registerForRichNotifications()
}
// iOS 9 support
else if #available(iOS 9, *) {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
}
// iOS 7 support
else {
application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
}
FirebaseApp.configure()
Messaging.messaging().shouldEstablishDirectChannel = true
return true
}
func registerForRichNotifications() {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { (granted:Bool, error:Error?) in
if granted {
print("Permission granted")
} else {
print("Permission not granted")
}
}
//actions defination
let action1 = UNNotificationAction(identifier: "action1", title: "Action First", options: [.foreground])
let action2 = UNNotificationAction(identifier: "action2", title: "Action Second", options: [.foreground])
let category = UNNotificationCategory(identifier: "actionCategory", actions: [action1,action2], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
} else {
// Fallback on earlier versions
}
}
// Push notification received
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
// Print notification payload data
print("Push notification received: \(data)")
AppDelegate.backgrndShared(num:1)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Swift.Void) { // If you are receiving a notification message while your app is in the background, // this callback will not be fired till the user taps on the notification launching the application. // TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics // Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID. if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") }
// Print full message. print(userInfo)
AppDelegate.fcmmessage = "app is off didReceiveRemoteNotification";
AppDelegate.backgrndShared(num:3)
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
// Point for handling the local notification when the app is open.
// Showing reminder details in an alertview
AppDelegate.backgrndShared(num:6)
}
public static func backgrndShared(num:Int)
{
let preferences = UserDefaults.standard
let currentLevel = num
let currentLevelKey = "currentLevel"
preferences.set(currentLevel, forKey: currentLevelKey)
preferences.synchronize()
}
public static func notify(){
if #available(iOS 10.0, *) {
let notification = UNMutableNotificationContent()
notification.title = "ANZEN"
notification.subtitle = "custom local notification"
notification.body = "fcm postman testing."
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "notification1", content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler:nil)
} else {
// Fallback on earlier versions
}
}
//////////////
// Called when APNs has assigned the device a unique token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Convert token to string
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
// Print it to console
print("APNs device token: \(deviceTokenString)")
AppDelegate.devicetokenString = deviceTokenString
// Persist it in your backend in case it's new
}
// Called when APNs failed to register the device for push notifications
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
// Print the error to console (you should alert the user that registration failed)
print("APNs registration failed: \(error)")
// AppDelegate.devicetokenString = "error"
}
////////////
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}