Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribing to topic on first app start fails without bg notifications and direct channel #1561

Closed
herrernst opened this issue Jul 19, 2018 · 15 comments
Assignees
Milestone

Comments

@herrernst
Copy link

@herrernst herrernst commented Jul 19, 2018

[REQUIRED] Step 2: Describe your environment

  • Xcode version: 9.4.1
  • Firebase SDK version: 5.4.0
  • Firebase Component: Messaging
  • Component version: 3.0.3

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

Create a new project as described in https://firebase.google.com/docs/cloud-messaging/ios/client. Notably, don't set up a direct channel; and don't enable silent background notifications.

Try to subscribe to a topic on first app start after permissions are granted. Subscription will fail with error code 501 (kFIRMessagingErrorCodeMissingDeviceID). If logging is enabled, "Device check in error, no auth credentials found" is printed before.

(Tested on iOS 11.4 device.)

Relevant Code:

Use Messaging_Sample_iOS slightly modified by me here: https://github.com/herrernst/firebase-ios-sdk/tree/subscribing-bug.

Add a GoogleService-Info.plist. On first app start (remove app before trying again), click "Request User Notifications". The completion block of subscribeToTopic will be called with an error. (You can probably ignore the thread checker warnings complaining about UI updates from background threads.)

@morganchen12
Copy link
Contributor

@morganchen12 morganchen12 commented Jul 19, 2018

You won't be able to subscribe successfully before the FCM token is first fetched. In your example, this code should be moved to your implementation of this MessagingDelegate method.

@herrernst
Copy link
Author

@herrernst herrernst commented Jul 19, 2018

Thank you. But why does it work when a direct channel setup is requested, or when silent background notifications are enabled?

@morganchen12
Copy link
Contributor

@morganchen12 morganchen12 commented Jul 19, 2018

IIRC requesting notification permissions via registerForRemoteNotifications affects the IID fetch process, but I'm fuzzy on the details. @chliangGoogle can probably answer in more detail.

@herrernst
Copy link
Author

@herrernst herrernst commented Jul 19, 2018

Also, the documentation you linked about -messaging:didReceiveRegistrationToken: says: "Typically it will be called once per app start, but may be called more often." But what if I want to subscribe to a topic later on, when the delegate method has already been called?
In other words, how do I know if I will be able to successfully subscribe to a topic, or if a have to wait for -messaging:didReceiveRegistrationToken:?

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Jul 19, 2018

I can't reproduce the error you had by calling subscription too early or without any checkin credentials. Seem like your client's direct channel credentials are corrupted for some reason.

With the latest FCM (v3.0.3) your subscription should suspend without a token. Regardless of MCS connection or background notification. And Firebase do request a token during initialization(if you didn't disable auto init flag), and as long as you put subscription in the code Morgan suggested, should be working for you.

If you continue to see kFIRMessagingErrorCodeMissingDeviceID error after the suggested fix, please file me a bug on this.

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Jul 19, 2018

Actually with the latest FCM (v3.0.3) you should be able to call subscription any time and the operation will simply suspend if a token is not present. And the operation resumes any time a token is retrieved and your subscription can then complete.

Can you try with the latest fcm and send us debug log if you still encounter the issue? Make sure you add -FIRDebugEnabled to expand the debug logs.

@herrernst
Copy link
Author

@herrernst herrernst commented Jul 20, 2018

@chliangGoogle

Seem like your client's direct channel credentials are corrupted for some reason.

As I've said, I did not set up a direct channel.

Also, as I've mentioned, I'm already using the latest FCM (3.0.3), and my example is based on it, too. Of course I can send you the debug (next week), but you should be able to try it out yourself by running my example.

And the operation resumes any time a token is retrieved and your subscription can then complete.

Is there any notification posted or callback called when such a suspended subscription completes? Or can I query FCM which topics are successfully registered? I want to show the user feedback about the (successfully) registered topics.

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Jul 20, 2018

Your direct channel credentials is generated and used for token generation, regardless you are setting it up or not.

When the suspended subscription completes, it goes back to the same callback for your original subscription request.

@herrernst
Copy link
Author

@herrernst herrernst commented Jul 23, 2018

Ok, I've now looked at it a little bit more and added some more logging to the test case at https://github.com/herrernst/firebase-ios-sdk/tree/subscribing-bug.
When running the example app at first time, these things happen in order:

  • didReceiveRegistrationToken is called with an FCM token
  • When the button gets clicked, after confirming notification authorisation, topic subscription is called. At that time, the FCM token exists, but the subscription fails (why?)
  • In the meantime, APNS token is received
  • didReceiveRegistrationToken is NOT called anymore, so there's no point in putting the topic subscription there as it won't be called.

Note that subscribing will work at the second app start, even if I do nothing (i.e. not click the button) on the first app start.

Here's the debug log, I've redacted possible sensitive data: https://pastebin.com/raw/sNqUgiPf

So, again, if this is by design, I still don't know when and how to successfully subscribe to a topic on first app start.

When the suspended subscription completes, it goes back to the same callback for your original subscription request.

What callback do you mean? The completion block of subscribeToTopic? Because I never see that one getting called later if it was called with an error before.

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Jul 25, 2018

You are right, you should be able to call subscription any where not necessary inside the callback.

When subscription failed, the error (501) returns in the completion block. This is the case happened to you. So even if you get a token later, the completion block will not be triggered again since it's already returned with an error.
And Yes I meant the completion block of subscribeToTopic.

@morganchen12 Can you reproduce the case based on developer's repo? I'm able to reproduce once but not again.

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Jul 26, 2018

I'm able to reproduce by turn off direct channel and disable auto collection ( put FirebaseMessagingAutoInitEnabled in info.plist).

Thank you for reporting this issue, we are working on a fix for it.

@paulb777 paulb777 added this to the M31 milestone Jul 27, 2018
@herrernst
Copy link
Author

@herrernst herrernst commented Jul 31, 2018

@chliangGoogle Thanks for investigating this! BTW, I get this error regardless of FirebaseMessagingAutoInitEnabled being set in Info.plist

@MateuszKarwat
Copy link

@MateuszKarwat MateuszKarwat commented Aug 3, 2018

@chliangGoogle @herrernst I'm also facing this issue. Usually, I subscribe to 4 topics at some point and indeed the 1st one fails on a first launch with error code 501.

I use default values for both shouldEstablishDirectChannel and FirebaseMessagingAutoInitEnabled. In fact, I don't have such strings in my code whatsoever. Also, I use the same versions which @herrernst uses.

Let me know, if you need a debug log or something that might help.

@chliangGoogle
Copy link
Contributor

@chliangGoogle chliangGoogle commented Aug 7, 2018

The fix doesn't depend on the FirebaseMessagingAutoInitEnabled flag. We found out checkin is not considered valid during app first start, causing the very first call always failed. So this fix should resolve your issues.

This should be fixed in the next release; please re-open this issue if it regresses past that point.

@haterecoil
Copy link

@haterecoil haterecoil commented Sep 16, 2018

Hello,

Thanks for the hard work!

As a piece of information, I had the same error today and fixed it by setting in plist.info

<key>FirebaseMessagingAutoInitEnabled</key>
<true/>

It used to be set to false, I guess I did some bad fiddling.

@firebase firebase locked and limited conversation to collaborators Oct 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants