-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
Referral Notifications - FCM Push Notifications #2667
Conversation
app/src/org/commcare/services/CommCareFirebaseMessagingService.java
Outdated
Show resolved
Hide resolved
|
||
/** | ||
* This method purpose is to show notifications to the user when the app is in the foreground. | ||
* When the app is in the background, FCM is responsible for notifying the user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the app is in the background, FCM is responsible for notifying the user
Is that true for data notifications as well ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed this, but it seems to have been answered here
@damagatchi retest this please? |
@damagatchi retest this please |
5213793
to
43dd926
Compare
Map<String, String> payloadData = remoteMessage.getData(); | ||
RemoteMessage.Notification payloadNotification = remoteMessage.getNotification(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a notification contains both data
and notification
object ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. My understanding is that the main difference is when the app is in the background, the SDK doesn't call onMessageReceived
only triggers the notification, i.e. if we want the sync
to happen regardless of whether the app is in the foreground or background, we shouldn't have a notification
object in the message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't completely understand. How do we handle the sync
notifcation when the app is in background ? Do we just discard the notification ? Or it's routed thorough a different pathway ?
Also when onMessageReceived
gets called (app is in foreground), It seems like we can only have one of notification
or data
payload. In that case it might make more sense to rearrange the code flow as -
if (payloadNotification != null) {
showNotification(payloadNotification);
} else if (payloadData.size() != 0){
/// process payloadData
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bumping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't completely understand. How do we handle the sync notifcation when the app is in background ? Do we just discard the notification ? Or it's routed thorough a different pathway ?
Yeah, this is a bit tricky. So, when the app is in the background and the message contains a notification
object, Firebase SDK takes care of delivering the notification to the Notification Drawer. In case the message also contains a data
object, Firebase SDK adds it to the extras of the intent of the launcher activity of the app. This is the default behaviour, so when the user taps the notification it opens the app launcher with the data
object as an extra.
Also when onMessageReceived gets called (app is in foreground), It seems like we can only have one of notification or data payload.
We can have both, but in this case because we want to trigger the sync when the app is in the background too, we are having messages with only the data
object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case the message also contains a data object, Firebase SDK adds it to the extras of the intent of the launcher activity of the app. This is the default behaviour, so when the user taps the notification it opens the app launcher with the data object as an extra.
That means we should be handling these intents on app startup right ? Or they by default gets delivered to this messaging service when user clicks on notification and pull the app in foreground ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shubham1g5 This is supposed to be handled on app startup but it's not yet implemented because our current implementation on HQ doesn't trigger FCM messages with both notification
and data
objects (see image below). So, the intention is to incorporate that on a later stage depending on the feedback we get as well, however, not in the scope of this work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not we still need to handle only data
messages that gets send when app is in background ? if not, How does the app handle sync data messages that gets delivered to the phone when the CC is in background ? For ex, my current understanding is -
- We trigger a notification with Action 'Background Sync' and type data messages
- This notification gets delivered to phone when CC is in background. Therefore Firebase adds the notification to the notification drawer ? (Not sure if it's true for only data messages)
- On clicking notification, Firebase launches CC with the intent containing data action. But since we are not handling intents with data payload, background sync doesn't get triggered.
Does it sound right to you ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the message
doesn't contain a notification
object and the app is in the background, the message is delivered to the FCM Service, so the onMessageDelivered
is called. More about this can be found here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it, thanks for confirming.
* This class is to facilitate handling the FCM Message Data object. It should contain all the | ||
* necessary checks and transformations | ||
*/ | ||
public class FCMMessageData { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: best to put this model in a new file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shubham1g5 This was done on #2680 in this commit
sharedPreferences.edit().putLong(FCM_TOKEN_TIME,System.currentTimeMillis()).apply(); | ||
} | ||
|
||
public static String removeServerUrlFromUserDomain(String userDomain) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method checkUserAndDomain
was moved to the FirebaseMessagingDataSyncer
class in this commit
FCMMessageData fcmMessageData = new FCMMessageData(payloadData); | ||
|
||
switch(fcmMessageData.action){ | ||
case SYNC -> {} // trigger sync for fcmMessageData |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should call setPendingSyncRequestFromServer
here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@damagatchi retest this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks safe to merge, we can continue any followups from here in other PRs. We should do a pass on lint errors before merging as well.
f14f4ba
to
065c2c9
Compare
@@ -46,4 +51,19 @@ public static String removeServerUrlFromUserDomain(String userDomain) { | |||
} | |||
return userDomain; | |||
} | |||
|
|||
public static void verifyToken() { | |||
if(!BuildConfig.DEBUG) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not init token in debug ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing in particular, just trying to avoid noise but I'm happy to revert that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah we should revert to be able to have receive push notifications with debug apk as well.
private static String getISO8601FormattedLastSyncTime() { | ||
long lastSyncTime = SyncDetailCalculations.getLastSyncTime(); | ||
if (lastSyncTime == 0) { | ||
// TODO: Move this method to DateUtils |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pending todo
Map<String, String> payloadData = remoteMessage.getData(); | ||
RemoteMessage.Notification payloadNotification = remoteMessage.getNotification(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bumping
@damagatchi retest this please |
5 similar comments
@damagatchi retest this please |
@damagatchi retest this please |
@damagatchi retest this please |
@damagatchi retest this please |
@damagatchi retest this please |
c2b72b4
to
a9a7d18
Compare
Summary
This is the first PR related with the implementation of the Referral Notification feature. This part is responsible for the integration of CommCare with Firebase Cloud Message (FCM) as the channel to be used when sending Push Notifications to CommCare apps. The Push Notifications are supposed to trigger syncs in CommCare, when certain conditions are met, allowing the user access to newly created referrals.
In order to test the service, follow the steps below:
https://fcm.googleapis.com/v1/projects/<FIREBASE_PROJECT_ID>/messages:send
with the request boby in the following format:Safety Assurance
cross-request: dimagi/commcare-core#1275