Closed codevalley closed 8 years ago
You are right this behavior is not clearly explained and I have my little idea about it...
Are you sure your issue is fondamentally different from https://github.com/firebase/quickstart-android/issues/89?
Why do you say that?
Are you sure you app is not Force Stopped when you put it in background?
First check if your device receives the message. Have a look at the logcat view and see if you receive such kind of messages:
mm-dd hh:ii:ss.nnn 1461-1461/? W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10000000 pkg=com.your.package (has extras) } If no, maybe you don't ue the right token.
If yes, please tell us what Android Studio version do you use.
@2ndGAB After scouring the internet I am relieved to atlast find someone interested in this issue, and actively being investigated.
That aside, I am pretty sure my app is alive, (see steps to reproduce). This happens specifically in doze mode AFAIK.
In fact, I don't think an app has to be alive for it to trigger onMessageReceived
, since it has com.google.firebase.MESSAGING_EVENT
intent-filter in Manifest. The messaging service will be initiated on a new message. But, when you force close an app, Android as a precaution does not start its services again, until user explicitly opens the app. This is to make sure some malicious/malfunctioning app does not go into a crash loop through its service.
In my case, though, I don't force close the app, in fact, I don't even have to minimize the app. I leave the app on foreground. Just get phone go to doze mode. Everything stops there.
mm-dd hh:ii:ss.nnn 1461-1461/? W/GCM-DMM: broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10000000 pkg=com.your.package (has extras) } If no, maybe you don't ue the right token.
Just tested this after seeing your comment. I don't get anything similar to the above mentioned log, in both cases (when I receive the message, when I don't).
I have never missed a downstream message, just that the delivery is gettin deffered if the phone is idle.
I use both Android Studio 2.1.2 and 2.2.6 both with Instant Run disabled.
@codevalley According to my tests, the mentioned message is not always displayed on all devices.
I'm not sure about the state of the application when it's left in foreground but the phone in doze mode.
Anyway does your message fire onMessageReceive() when the application is in background?
I tried to execute adb commands you mentioned. I don't know what it's supposed to change on the device but it doesn't change anything visually. The second command replies by:
Stepped to: ACTIVE
Is it correct?
In that situation, the message fires onMessageReceive()
@2ndGAB No. That's the whole problem. All I want is to get onMessageReceive()
.
So, maybe I could propose you to install Android Studio 1.5 beside your 2.1.2 version, and try to build you project from 1.5 without changing anything and see....
@2ndGAB it worked for you?
@codevalley perfectly as strange as it appears. I made lot of tests exposed here
@codevalley I assume you are calling adb shell dumpsys deviceidle step
till the device is Stepped to: IDLE
. In that case the device should receive the data message when priority is high and the message should never be delivered when priority is normal and ttl is 0.
It seems that your time_to_live
, delay_while_idle
and priority
fields are being ignored, assuming that you left them out, what you are seeing would be expected. So looks like for some reason either these fields are not being sent to FCM or when they get to FCM they are being ignored. Could you add your GAE code that you are using to send the request to FCM?
@kroikie I haven't left those params out. This is my GAE function to send a message (downstream).
public void messageUser(String token, String dataJson) {
try {
String json = "{\n" +
" \"to\": \""+ token + "\",\n" +
" \"priority\": \"high\",\n" +
" \"delay_while_idle\": false ,\n" +
" \"data\": " + dataJson +
" \"time_to_live\": 0 ,\n" +
"}";
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(FCM_URL);
post.addHeader("Content-Type", "application/json");
post.addHeader("Authorization","Key="+SERVER_KEY);
StringEntity postingString = new StringEntity(json);//gson.tojson() converts your pojo to json
post.setEntity(postingString);
HttpResponse resp = httpClient.execute(post);
apiResponse = EntityUtils.toString(resp.getEntity());
} catch (Exception e) {
apiResponse = "Error " + e.toString();
}
}
@codevalley thanks for the function, I wonder if your json is formatted the way you expect from the String. The json String that you are generating seems to be missing a comma after the dataJson String unless that string contains a comma itself. Could you possibly log the resulting json string and post it here?
Ok. let me do it.
@kroikie Here is the final json.
{
"to": "c6NgGf6D.......vPNqHSN",
"priority": "high",
"delay_while_idle": false ,
"time_to_live": 0 ,
"data": {"buttons":7,"delay":0,"fromKey":"iS1ogJEI...i9Mxnz2","response":0,"timestamp":0,"toKey":"T1sg....Ea2"}
}
Sorry for the confusion around the 'comma', the running version has data in the end, I changed while tinkering around it see if something was wrong in the order. The json shown above is from actual GAE log.
@codevalley the format of your request looks good, the data message should be delivered even if the device is in doze mode. Are you running into this issue while using this sample? Or are you using a different application.
I have run this sample on a Nexus 5X and I have not seen this issue. Also v9.4.0 was recently released could you update your dependencies to match those in this sample and try again. I'm especially curious about the results you are getting on the Nexus 5X.
@kroikie This is weird. I upgraded to 9.4 and it is now working. I tested on 5x (Nougat preview), Nexus 5 (6.0.1) and Note 4 (6.0.1). Not sure how this got fixed, because I had upgraded to 9.4 yesterday and tested once after that, it didn't seem to work then. Anyways, I will test a little more today with this new build on different devices and confirm the fix and close this ticket. PS. Purely out of curiosity, would you mind testing this with v9.2.1 and see if you are able to reproduce this on that?
@kroikie Did extensive testing yesterday. Here are the inferences.
Hence I can the issue is resolved (mostly). My doubt is if Doze/Idle are two different states? And when device is on doze, no FCM messages come through? It is almost like device is in hibernation?
@codevalley I have tried the sample in doze mode using the adb commands and if I send a message with ttl 0 while the device is in doze mode (IDLE) it never receives the message, with both 9.2.1 and 9.4.0. Can you confirm that when you are using adb shell dumpsys deviceidle step
that you are using it repeatedly till the response is Stepped to: IDLE
?
Glad to hear that it seems to be working when the device is "really" in doze mode, but you should be able to simulate it with adb.
@kroikie Actually it is not working when the device organically dozes (overnight).
So does it actually mean IDLE != DOZE ? Also, based on your own tests ( and not receiving messages), is it now confirmed that there is a delivery bug related to Doze in FCM?
@codevalley to clarify:
If you are using high priority then you should expect to see the notifications coming in even when the phone is in IDLE/Doze, while IDLE and DOZE may not be the same thing FCM messages should be treated the same. ie Delivered if priority is high and not delivered otherwise.
It's difficult for me to define what you are seeing as a bug since I'm not able to reproduce it. It works as expected for me. If this issue persists what I would do is run your test cases and when you get the results you are seeing generate a bug report on the android device, along with the times and states the device was in and make a report to Firebase Support. Add my name to the report (Arthur Thompson) and I will pick it up and dig deeper to help resolve your issue.
I think however it is beyond the scope of this sample so I'm going to close this issue.
@kroikie No problem. Just to clarify though,
if I send a message with ttl 0 while the device is in doze mode (IDLE) it never receives the message, with both 9.2.1 and 9.4.0.
does that mean you could reproduce the bug?
@codevalley no it means that I was not able to reproduce the bug. If device is in doze mode (IDLE) then:
This is what I am seeing on both 9.2.1 and 9.4.0
Maybe this helps: https://developer.android.com/training/monitoring-device-state/doze-standby.html#understand_doze
I found it a great explanation of delivery behaviour for both Doze and App Standby.
@codevalley hello from future :D I currently have exactly the same behavior you had... where you able to solve the issue? If you remember could you provide the conclusion, please?
Hello @codevalley and @kroikie and @KhaledJU I am exactly in the same issue can you guys let me know the solution. This issue has eaten my precious time of almost a week . Please help
My environment
Problem.
I tried executing the sample code. And to send downstream FCM, I have used GAE and have sent a message with following fields.
I am not able to receive the message, until I unlock the phone (bring it out of idle state). In this process, it is ignoring two parameters set when sending the message
I combed through available documentations for FCM delivery, and they only explicitly mention behaviours for FCM with "notification" tag, FCM with "notification" and "data" tag. They don't clearly callout the behaviour when there is only "data" tag.
It feels like the message is getting delivered according to the params, but it is sent to the listener only on device wake up. Can this be the case? Because the POST response returns success and message_id instantenously.
PS: I believe this issue is fundamentally different from Issue #89 which was because the app was getting killed.
Steps to reproduce:
Send notification with above mentioned structure.
Results.
The message does not get delivered to the
MyFirebaseMessagingService
instance. Leave the phone in idle for indefinite time and unlock the phone. The message gets delivered immediately.Expected Results:
Message should get delivered immediately (priority: high) or it should be discarded on unsuccessful delivery (ttl:0)