ostownsville / cordova-plugin-fcm

Google FCM Push Notifications Cordova Plugin
21 stars 17 forks source link

iOS 10.0 Fix #4

Closed chrisjpalmer closed 7 years ago

chrisjpalmer commented 7 years ago

Still want to resolve these before we merge: 1) LN 74: Its hard to tell from the FCM documentation whether didReceiveRemoteNotification will be fired on iOS 10 as well as willPresentNotification. If it does then we need to put the 'short circuit' code back in didReceiveRemoteNotification to stop the notification being recognised twice by the plugin

2) It would seem that in iOS 10, content-available=1 messages don't work anymore. Is this correct?

2) LN:118 Might be a problem here if applicationDidBecomeActive is called before didReceiveNotificationResponse. This would result in the notification not being recognised by the plugin because of the newly implemented [self notifyOfMessage] function which stores the data instead of sending it to javascript IF wasTapped = true. Just not sure if iOS calls it before the app goes into the foreground OR when it goes into the foreground

3) I removed this code [[FIRMessaging messaging] subscribeToTopic:@"/topics/ios"]; [[FIRMessaging messaging] subscribeToTopic:@"/topics/all"]; because it is not necessary to start receiving notifications. However is it a feature of the plugin that these particular topics are automatically subscribed to?

ostownsville commented 7 years ago

@chrisjpalmer

Regarding the comments

Point 1 I found this for: willPresentNotification The firebase blog post is mentioning how it works if the newer method is not available, I would assume that, if the newer method is there, the old one is not called, that would be common sense.

userNotificationCenter:willPresentNotification: 

Called when a notification is delivered to a foreground app.

Firebase Blog
https://firebase.googleblog.com/2016/09/announcing-firebase-36-for-ios.html

Firebase Cloud Messaging now has support for the new iOS 10 user notifications. 
If your app is running on iOS 10, you can handle incoming notifications using the 
userNotificationCenter:willPresentNotification: withCompletionHandler method. 
And don't worry -- if your app only has the older 
application:didReceiveRemoteNotification: completionHandler methods supported, 
APNs will call those instead if it can't find the newer ones.

Point 2 I found this https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html

The sending of a silent notification requires a special configuration of the notification’s payload. 
If your payload is not configured properly, the notification might be displayed to the user 
instead of being delivered to your app in the background. In your payload, make sure the 
following conditions are true:
The payload’s aps dictionary must include the content-available key with a value of 1.
The payload’s aps dictionary must not contain the alert, sound, or badge keys.

Point 3 I guess, if the app is active, it is in foreground and otherwise in background. So, I think that is fine.

didReceiveRemoteNotification 
is called when the app is in background and after tap.
So, the app would never be active at the time this method is called, I believe.

applicationReceivedRemoteMessage
Called when notification is delievered in foregound, app would be active

Point 4 Not sure, I have never used the channels, I guess some testing is needed.

ostownsville commented 7 years ago

I merge this now and do some testing over the next few days to see the behavior in some different cases. All my test so far were working fine.

chrisjpalmer commented 7 years ago

Awesome thanks for that.

Im sorry I can't test... I don't have access to an iPhone atm.

On the comments:

Point 1: Great research. This looks like the answer.

Point 2: A few blog posts hinted that silent notifications were no longer working but I think for now we should assume they are on the basis of no obvious signs from Apple.

Point 2.1 Point 2 tangent:

I am unsure as to which event handler silent notifications will propagate through. A silent notification (in order to be successful) must contain nothing in the aps dictionary => therefore on the FCM side you leave out the notification object in the payload.

FCM deals with these kinds of messages differently in iOS 10. Instead of sending them through APNS, it sends them through the direct FCM channel to the device. Logic says, you should expect to find the notification propagating through the new messaging:didRecieveMessage: event (part of the new FCMNotificationDelegate).

However in theory this should not work when the application is asleep AS only APNS has the ability to wake the application and allow background execution. For this reason I guessed that they will propagate through userNotificationCenter:willPresentNotification:.

Point 3: Yes I agree with you. I think we should be okay here.

For iOS 9, application.applicationState will be either inactive or background and I believe applicationDidBecomeActive: won't get called until applicationState == active.

For iOS 10 there is a dedicated handler for the tap event and I assume this must get called before applicationDidBecomeActive:

screen shot 2017-09-06 at 5 52 29 pm

Point 3.1 Point 3 Tangent:

Would it be prudent to include the UIApplicationBackgroundState in the if statement here just to be thorough? if (state == UIApplicationStateInactive || state == UIApplicationStateBackground )

Point 4: As long as its consistent with the android side of the plugin, there are no issues.

CowboyCode commented 7 years ago

All good points, the documentations for firebase and apple ios are often outdated or short. Good to keep an eye on the firebase changelog as well. https://firebase.google.com/support/release-notes/ios 4.0.0 had breaking updates, which should be covert already.

We can add logs to test the app flow, for the test cases, the xcode logs are good to watch running an app live.

I will do some more testing tomorrow...

CowboyCode commented 7 years ago

And we have a new firebase ios sdk version 4.1.1 lol I add that tomorrow as well

chrisjpalmer commented 7 years ago

Excellent! Are you testing on iOS 9 or iOS 10?

CowboyCode commented 7 years ago

I will test ios 10

CowboyCode commented 7 years ago

Test results

Tested with iphone 6, ios v. 10.3.3

@chrisjpalmer I added some more visible logs, the numbers...

Notification -> app in background

2017-09-07 13:18:56.793905+1000 ProjectName[810:359970] userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: 2017-09-07 13:18:56.794004+1000 ProjectName[810:359970] didReceiveNotificationResponse -> 33333333:

2017-09-07 13:18:56.794256+1000 ProjectName[810:359970] Notification 888888 Data: <7b22646f 63223a22 222c2268 65616465 72223a22 4e6f7469 66696361 74696f6e 20486561 64657222 2c227761 73546170 70656422 3a747275 652c2263 68616e6e 656c7322 3a225b5c 22546573 74204368 616e6e65 6c5c225d 222c2261 7073223a 7b22616c 65727422 3a7b2274 69746c65 223a224e 6f746966 69636174 696f6e20 48656164 6572222c 22626f64 79223a22 4e6f7469 66696361 74696f6e 20426f64 79227d2c 22736f75 6e64223a 22646566 61756c74 222c2263 61746567 6f727922 3a224643 4d5f504c 5547494e 5f414354 49564954 59227d2c 226d6573 73616765 223a224e 6f746966 69636174 696f6e20 426f6479 222c2263 72656174 6564223a 22313530 34373534 33323430 3030222c 22636f6e 74656e74 5f617661 696c6162 6c65223a 22747275 65222c22 70616765 223a2222 2c227479 7065223a 22706167 65222c22 67636d2e 6d657373 6167655f 6964223a 22303a31 35303437 35343332 36333433 39393425 37646631 65613361 37646631 65613361 227d>

2017-09-07 13:18:56.794382+1000 ProjectName[810:359970] notifyOfMessage:withTapInfo: => wasTapped = true... therefore going to store the data and send when app returns to the foreground 77777777

2017-09-07 13:18:56.794419+1000 ProjectName[810:359970] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called. 2017-09-07 13:18:56.836419+1000 ProjectName[810:359970] [CodePush] Checking for update. 2017-09-07 13:18:57.634445+1000 ProjectName[810:359970] [CodePush] App is up to date.

2017-09-07 13:18:58.155353+1000 ProjectName[810:359970] applicationDidBecomeActive: 2017-09-07 13:18:58.155455+1000 ProjectName[810:359970] applicationDidBecomeActive -> 5555555:

2017-09-07 13:18:58.155498+1000 ProjectName[810:359970] notifyOfMessage: => executing javascript callback 2017-09-07 13:18:58.155563+1000 ProjectName[810:359970] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"doc":"","header":"Notification Header","wasTapped":true,"channels":"[\"Test Channel\"]","aps":{"alert":{"title":"Notification Header","body":"Notification Body"},"sound":"default","category":"FCM_PLUGIN_ACTIVITY"},"message":"Notification Body","created":"1504754324000","content_available":"true","page":"","type":"page","gcm.message_id":"0:1504754326343994%7df1ea3a7df1ea3a"});

Notification app in foreground

2017-09-07 13:22:46.903479+1000 ProjectName[810:359970] userNotificationCenter:willPresentNotification:withCompletionHandler: 2017-09-07 13:22:46.903632+1000 ProjectName[810:359970] willPresentNotification:true -> 22222222:

2017-09-07 13:22:46.904125+1000 ProjectName[810:359970] Notification 888888 Data: <7b22646f 63223a22 222c2268 65616465 72223a22 4e6f7469 66696361 74696f6e 20486561 64657222 2c227761 73546170 70656422 3a66616c 73652c22 6368616e 6e656c73 223a225b 5c225465 73742043 68616e6e 656c5c22 5d222c22 61707322 3a7b2261 6c657274 223a7b22 7469746c 65223a22 4e6f7469 66696361 74696f6e 20486561 64657222 2c22626f 6479223a 224e6f74 69666963 6174696f 6e20426f 6479227d 2c22736f 756e6422 3a226465 6661756c 74222c22 63617465 676f7279 223a2246 434d5f50 4c554749 4e5f4143 54495649 5459227d 2c226d65 73736167 65223a22 4e6f7469 66696361 74696f6e 20426f64 79222c22 63726561 74656422 3a223135 30343735 34353634 30303022 2c22636f 6e74656e 745f6176 61696c61 626c6522 3a227472 7565222c 22706167 65223a22 3131222c 22747970 65223a22 70616765 222c2267 636d2e6d 65737361 67655f69 64223a22 303a3135 30343735 34353635 38373839 31342537 64663165 61336137 64663165 61336122 7d>

2017-09-07 13:22:46.904234+1000 ProjectName[810:359970] notifyOfMessage: => executing javascript callback 2017-09-07 13:22:46.904458+1000 ProjectName[810:359970] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"doc":"","header":"Notification Header","wasTapped":false,"channels":"[\"Test Channel\"]","aps":{"alert":{"title":"Notification Header","body":"Notification Body"},"sound":"default","category":"FCM_PLUGIN_ACTIVITY"},"message":"Notification Body","created":"1504754564000","content_available":"true","page":"11","type":"page","gcm.message_id":"0:1504754565878914%7df1ea3a7df1ea3a"});

Message -> app in background

2017-09-07 13:32:21.949450+1000 ProjectName[810:359970] messaging:didReceiveMessage:remoteMessage: 2017-09-07 13:32:21.949609+1000 ProjectName[810:359970] didReceiveMessage -> 4444444444:

2017-09-07 13:32:21.950025+1000 ProjectName[810:359970] Notification 888888 Data: <7b226672 6f6d223a 22373032 39343935 37383231 38222c22 646f6322 3a226874 7470733a 5c2f5c2f 73332d61 702d736f 75746865 6173742d 322e616d 617a6f6e 6177732e 636f6d5c 2f6f7261 636c6564 65765c2f 6465765c 2f646f63 756d656e 74735c2f 6c6f676f 2e706466 222c2268 65616465 72223a22 64736664 7366222c 22636861 6e6e656c 73223a22 5b5c2254 65737420 4368616e 6e656c5c 225d222c 22776173 54617070 6564223a 66616c73 652c226d 65737361 6765223a 22666473 66647322 2c226372 65617465 64223a22 31353034 37353531 32363030 30222c22 636f6c6c 61707365 5f6b6579 223a2264 73666473 66222c22 636f6e74 656e745f 61766169 6c61626c 65223a22 31222c22 70616765 223a2238 30222c22 74797065 223a2270 61676522 7d>

2017-09-07 13:32:21.950130+1000 ProjectName[810:359970] notifyOfMessage: => executing javascript callback 2017-09-07 13:32:21.951014+1000 ProjectName[810:359970] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"from":"702949578218","doc":"https:\/\/s3-ap-southeast-2......","header":"Header","channels":"[\"Test Channel\"]","wasTapped":false,"message":"Message text","created":"1504755126000","collapse_key":"blabla","content_available":"1","page":"80","type":"page"});

Message -> app in foreground

2017-09-07 13:37:26.117947+1000 ProjectName[810:359970] messaging:didReceiveMessage:remoteMessage: 2017-09-07 13:37:26.118103+1000 ProjectName[810:359970] didReceiveMessage -> 4444444444:

2017-09-07 13:37:26.118530+1000 ProjectName[810:359970] Notification 888888 Data: <7b226672 6f6d223a 22373032 39343935 37383231 38222c22 646f6322 3a22222c 22686561 64657222 3a224d65 73736167 65204865 61646572 2c206973 20696e20 64617461 222c2263 68616e6e 656c7322 3a225b5c 22546573 74204368 616e6e65 6c5c225d 222c2277 61735461 70706564 223a6661 6c73652c 226d6573 73616765 223a224d 65737361 67652062 6f64792c 20697320 696e2064 61746122 2c226372 65617465 64223a22 31353034 37353534 34343030 30222c22 636f6c6c 61707365 5f6b6579 223a224d 65737361 67652048 65616465 722c2069 7320696e 20646174 61222c22 636f6e74 656e745f 61766169 6c61626c 65223a22 31222c22 70616765 223a2233 37222c22 74797065 223a2270 61676522 7d> 2017-09-07 13:37:26.118687+1000 ProjectName[810:359970] notifyOfMessage: => executing javascript callback

2017-09-07 13:37:26.119283+1000 ProjectName[810:359970] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"from":"702949578218","doc":"","header":"Message Header, is in data","channels":"[\"Test Channel\"]","wasTapped":false,"message":"Message body, is in data","created":"1504755444000","collapse_key":"Message Header, is in data","content_available":"1","page":"37","type":"page"});

Message -> app in foreground -> removed "content-available" from data block, must be there and 1 to work, looking at the apple docs.

-> Received the message silent

2017-09-07 13:41:29.215576+1000 ProjectName[810:359970] messaging:didReceiveMessage:remoteMessage: 2017-09-07 13:41:29.215737+1000 ProjectName[810:359970] didReceiveMessage -> 4444444444:

2017-09-07 13:41:29.216351+1000 ProjectName[810:359970] Notification 888888 Data: <7b226672 6f6d223a 22373032 39343935 37383231 38222c22 646f6322 3a22222c 22686561 64657222 3a224865 61646572 20546563 74222c22 6368616e 6e656c73 223a225b 5c225465 73742043 68616e6e 656c5c22 5d222c22 77617354 61707065 64223a66 616c7365 2c226d65 73736167 65223a22 426f6479 20546578 74222c22 63726561 74656422 3a223135 30343735 35363836 30303022 2c22636f 6c6c6170 73655f6b 6579223a 22486561 64657220 54656374 222c2274 79706522 3a227061 6765222c 22706167 65223a22 3535227d> 2017-09-07 13:41:29.216458+1000 ProjectName[810:359970] notifyOfMessage: => executing javascript callback

2017-09-07 13:41:29.216581+1000 ProjectName[810:359970] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"from":"702949578218","doc":"","header":"Header Tect","channels":"[\"Test Channel\"]","wasTapped":false,"message":"Body Text","created":"1504755686000","collapse_key":"Header Tect","type":"page","page":"55"});

Message -> app in background -> removed "content-available" from data block, must be there and 1 to work, looking at the apple docs.

Apparently, it does not matter if "content_available" is set or not....

-> received message

2017-09-07 13:54:32.754882+1000 ProjectName[826:365788] applicationDidBecomeActive: 2017-09-07 13:54:32.754971+1000 ProjectName[826:365788] applicationDidBecomeActive -> 5555555:

2017-09-07 13:54:33.478820+1000 ProjectName[826:365788] messaging:didReceiveMessage:remoteMessage: 2017-09-07 13:54:33.479178+1000 ProjectName[826:365788] didReceiveMessage -> 4444444444: 2017-09-07 13:54:33.479784+1000 ProjectName[826:365788] Notification 888888 Data: <7b226672 6f6d223a 22373032 39343935 37383231 38222c22 646f6322 3a22222c 22686561 64657222 3a224865 61646572 20546578 74222c22 6368616e 6e656c73 223a225b 5c225465 73742043 68616e6e 656c5c22 5d222c22 77617354 61707065 64223a66 616c7365 2c226d65 73736167 65223a22 426f6479 20546578 74222c22 63726561 74656422 3a223135 30343735 36343638 30303022 2c22636f 6c6c6170 73655f6b 6579223a 22486561 64657220 54657874 222c2274 79706522 3a227061 6765222c 22706167 65223a22 3337227d> 2017-09-07 13:54:33.479896+1000 ProjectName[826:365788] notifyOfMessage: => executing javascript callback 2017-09-07 13:54:33.480057+1000 ProjectName[826:365788] stringByEvaluatingJavaScriptFromString FCMPlugin.onNotificationReceived({"from":"702949578218","doc":"","header":"Header Text","channels":"[\"Test Channel\"]","wasTapped":false,"message":"Body Text","created":"1504756468000","collapse_key":"Header Text","type":"page","page":"37"});

Message -> Background -> content_available = 1 and setSound('default')

Should not work as message but come in as notification

-> Received as notification -> Interesting logs

2017-09-07 14:01:35.939798+1000 ProjectName[826:365788] applicationDidBecomeActive: 2017-09-07 14:01:35.939922+1000 ProjectName[826:365788] applicationDidBecomeActive -> 5555555:

2017-09-07 14:01:42.400854+1000 ProjectName[826:365788] applicationDidEnterBackground: 2017-09-07 14:01:42.400960+1000 ProjectName[826:365788] applicationDidEnterBackground -> 6666666:

2017-09-07 14:01:45.382866+1000 ProjectName[826:365788] userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: 2017-09-07 14:01:45.382944+1000 ProjectName[826:365788] didReceiveNotificationResponse -> 33333333:

2017-09-07 14:01:45.383416+1000 ProjectName[826:365788] Notification 888888 Data: <7b22646f 63223a22 222c2268 65616465 72223a22 48656164 65722054 65787422 2c227761 73546170 70656422 3a747275 652c2263 68616e6e 656c7322 3a225b5c 22546573 74204368 616e6e65 6c5c225d 222c2261 7073223a 7b22616c 65727422 3a7b2274 69746c65 223a2248 65616465 72205465 7874222c 22626f64 79223a22 426f6479 20546578 74227d2c 22736f75 6e64223a 22646566 61756c74 222c2263 61746567 6f727922 3a224643 4d5f504c 5547494e 5f414354 49564954 59227d2c 226d6573 73616765 223a2242 6f647920 54657874 222c2263 72656174 6564223a 22313530 34373536 38363830 3030222c 22636f6e 74656e74 5f617661 696c6162 6c65223a 2231222c 22706167 65223a22 3535222c 22747970 65223a22 70616765 222c2267 636d2e6d 65737361 67655f69 64223a22 303a3135 30343735 36383639 39373635 30372537 64663165 61336137 64663165 61336122 7d> 2017-09-07 14:01:45.383475+1000 ProjectName[826:365788] notifyOfMessage:withTapInfo: => wasTapped = true... therefore going to store the data and send when app returns to the foreground 77777777

2017-09-07 14:01:45.383523+1000 ProjectName[826:365788] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.

chrisjpalmer commented 7 years ago

Ooh very interesting. Thanks so much for your testing.

So Im gonna go through systematically with the points and correlate your findings.

Point 1 As you predicted, in iOS 10 the notifications bypass the old AppDelegate routines: didReceiveRemoteNotification

Point 2 Silent notifications don't really have an effect. Perhaps this is a draw back of FCM, who knows. The app is not notified until the app is opened. You opened it manually (correct me if im wrong).

Point 2.1 The silent notifications are actually being treated as just plain old data notifications. This means when the app boots they get sent to messaging:didRecieveMessage:

Point 3 applicationDidBecomeActive: is called after the tap event on iOS 10! This is good, it means that we are always going to be able to deliver the event to javascript.

Point 3.1 Point 3.1 is more related to iOS 9, so we will have to test that.

Next Up Okay and Im gonna put up another PR to just add the competition handler in for userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: which is why you are getting that warning.

We need to put something in the README which says that silent notifications don't work in iOS 10.0. I will put that in my PR as well.