Mar*_*ian 34 ios firebase google-cloud-messaging swift firebase-cloud-messaging
我在iOS上遇到FCM通知问题.
我收到成功通知时,我的应用程序是在前台(回调didReceiveRemoteNotification中appdelegate被解雇),但是当应用程序在后台我没有收到通知(我看不出在iOS中的通知栏,任何东西).
所以,我认为问题在于FCM发送的消息格式.我的服务器发送给FCM的json采用以下格式:
{
"data":{
"title":"mytitle",
"body":"mybody",
"url":"myurl"
},
"notification":{
"title":"mytitle",
"body":"mybody"
},
"to":"/topics/topic"
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我的json中有两个块:一个通知块(用于接收后台通知)和一个数据块(用于接收前台通知).
我无法理解为什么没有收到后台通知.我的疑问是关于块的顺序(如果我在"通知"块之前放置"数据"块会有问题吗?).
编辑: 有关该问题的更多信息.
这是我的appdelegate.swift:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
var window: UIWindow?
// Application started
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
let pushNotificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
FIRApp.configure()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "tokenRefreshNotification:", name: kFIRInstanceIDTokenRefreshNotification, object: nil)
return true
}
// Handle refresh notification token
func tokenRefreshNotification(notification: NSNotification) {
let refreshedToken = FIRInstanceID.instanceID().token()
print("InstanceID token: \(refreshedToken)")
// Connect to FCM since connection may have failed when attempted before having a token.
if (refreshedToken != nil)
{
connectToFcm()
FIRMessaging.messaging().subscribeToTopic("/topics/topic")
}
}
// Connect to FCM
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
// Handle notification when the application is in foreground
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> 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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"])")
// Print full message.
print("%@", userInfo)
}
// Application will enter in background
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 throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
// Application entered in background
func applicationDidEnterBackground(application: UIApplication)
{
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
// Application will enter in foreground
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.
}
// Application entered in foreground
func applicationDidBecomeActive(application: UIApplication)
{
connectToFcm()
application.applicationIconBadgeNumber = 0;
}
// Application will terminate
func applicationWillTerminate(application: UIApplication)
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
Run Code Online (Sandbox Code Playgroud)
我可以在前台接收消息的唯一方法是禁用方法调配,在我的info.plist中将FirebaseAppDelegateProxyEnabled设置为NO.
在这种情况下,FCM文档说我必须在我的appdelegate.swift中实现两种方法:
- FIRMessaging.messaging().appDidReceiveMessage(userInfo) in didReceiveRemoteNotification callback
- FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox) in didRegisterForRemoteNotificationsWithDeviceToken callback
Run Code Online (Sandbox Code Playgroud)
但是如果我实现这些功能,即使应用程序处于前台,消息也会停止.
我知道这很奇怪.
编辑2:
当应用程序处于后台时,不会收到通知,但是当我打开我的应用程序时,会立即收到相同的通知(触发方法didReceiveRemoteNotification).
Chr*_*ris 23
假设您已正确设置所有内容,则将priority消息设置normal为" high应"会立即显示.这是由于iOS捆绑通知并处理它们的方式.您可以在此处阅读有关FCM通知的优先级.请注意,high除非有好的情况,否则你不应该真正用于生产,因为它有电池罚款.
以下是Apple文档的参考资料
通知的优先级.指定以下值之一:
10 - 立即发送推送消息.具有此优先级的通知必须在目标设备上触发警报,声音或徽章.将此优先级用于仅包含内容可用密钥的推送通知是错误的.
5 - 在考虑设备电源注意事项的时间发送推送消息.具有此优先级的通知可能会分组并以突发方式传递.它们被限制,在某些情况下不会被交付.如果省略此标头,则APNs服务器将优先级设置为10.
Kei*_*day 18
您需要将content_available属性设置为true,如下所示:
{
"data":{
"title":"mytitle",
"body":"mybody",
"url":"myurl"
},
"notification":{
"title":"mytitle",
"body":"mybody",
"content_available": true
},
"to":"/topics/topic"
}
Run Code Online (Sandbox Code Playgroud)
本部分中有一个蓝色的注释框,其中说明了这一点:https://firebase.google.com/docs/cloud-messaging/concept-options#notifications
CFP*_*ort 10
优先级和content_available(如其他答案中所述)是确保您收到通知的关键元素.测试显示了有趣的结果,所以我想在这里分享它们.
测试结果:Swift 3,Xcode 8,iOS 10
优先级="高"=>"立即"(在明显的网络延迟内)接收消息.
优先级="正常"=>各种结果(通常很快,但明显慢于"高")
通知中的content_available = true(无有效负载消息)
top_available =顶级为true(无有效负载消息)
通知中的content_available = true(带有消息{title/body})
top_available =顶级为true(带有效内容消息)
结论:
编辑:附加测试结果: - 如果你有一个msg标题你必须有一个msg正文或你没有得到警报.
这个奇怪的部分是你将获得振动,徽章和声音,但警报框不会出现,除非你有一个身体和标题.
| 归档时间: |
|
| 查看次数: |
34821 次 |
| 最近记录: |