Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[firebase_messaging] Android: Receiving Data messages if app terminated #1898

Closed
wants to merge 10 commits into from

Conversation

ivk1800
Copy link
Contributor

@ivk1800 ivk1800 commented Jul 24, 2019

Description

Adding support receiving data messages if app terminated on Android.

Related Issues

flutter/flutter#22072

flutter/flutter#31365
flutter/flutter#32751

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • [] Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

Copy link
Contributor

@collinjackson collinjackson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

flutter/flutter#22072 is a high priority issue and I'd love to get a fix landed.

I'm trying to wrap my head around this implementation and I'm curious how your approach compares to what React Native Firebase is doing. Let me know if you have any thoughts on that.

FlutterBackgroundMessagesReceiver has a lot of new code for building up notifications and sending them to the NotificationManager. I just want to make sure I understand why we need to do that. It sounds like we're going down different paths for notifications handling depending on whether data messages are enabled and I'm wondering if it would make more sense to handle all notifications the same way for consistency.

android:name="flutter.firebase.data.message"
android:value="true" />
```
2. implement onReceive method. onReceive called if app terminated or app in background.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. implement onReceive method. onReceive called if app terminated or app in background.
2. Implement the `onReceive` method. `onReceive` called if the app is terminated or in the background.

@@ -108,6 +108,35 @@ Future<void> _handleNotification (Map<dynamic, dynamic> message, bool dialog) as
}
````

## Receiving Data messages(Android)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Receiving Data messages(Android)
## Receiving data messages (Android)

@@ -88,7 +88,7 @@ Messages are sent to your Flutter app via the `onMessage`, `onLaunch`, and `onRe
| --------------------------: | ----------------- | ----------------- | -------------- |
| **Notification on Android** | `onMessage` | Notification is delivered to system tray. When the user clicks on it to open app `onResume` fires if `click_action: FLUTTER_NOTIFICATION_CLICK` is set (see below). | Notification is delivered to system tray. When the user clicks on it to open app `onLaunch` fires if `click_action: FLUTTER_NOTIFICATION_CLICK` is set (see below). |
| **Notification on iOS** | `onMessage` | Notification is delivered to system tray. When the user clicks on it to open app `onResume` fires. | Notification is delivered to system tray. When the user clicks on it to open app `onLaunch` fires. |
| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | *not supported by plugin, message is lost* |
| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | see "Receiving Data messages(Android)" |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | see "Receiving Data messages(Android)" |
| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | see "Receiving Data messages (Android)" |

@@ -1,3 +1,7 @@
## 5.2.0

* Android: Receiving Data messages if app terminated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Android: Receiving Data messages if app terminated
* On Android, now supports receiving data messages if the app is terminated.

/**
* Called when message is received.
*
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent intent = new Intent(ACTION_REMOTE_MESSAGE);
if (!isDataMessages) {
sendForegroundBroadcast(remoteMessage);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like you're broadcasting twice here if !isDataMessages evaluates to true. Is that what you intended? Should you return?

messageDataIntent.putExtra(key, value);
}

PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0);

The 123 here looks a little magical, perhaps we should move it out into a constant?


private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message";

static boolean isDataMessages(Context context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method name came across as a bit confusing.

* true, if application receive messages with type "Data messages" About FCM messages
* {@https://firebase.google.com/docs/cloud-messaging/concept-options}
*/
private boolean isDataMessages;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is private it probably doesn't need a doc comment.


private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message";

static boolean isDataMessages(Context context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this method name kind of confusing. I think it might make sense to call it dataMessagesEnabled since you're intending this as an app-wide flag. Would it make sense to just do something by default? React Native Firebase doesn't seem to have this flag so I'm wondering how the approaches compare.

@kroikie
Copy link
Contributor

kroikie commented Jul 24, 2019

@ivk1800 Thanks for the PR, could you provide more details on the exact problem that this PR is attempting to solve? Background messaging is an issue but I'm not sure if this PR addresses it completely.

@kroikie
Copy link
Contributor

kroikie commented Jul 24, 2019

It looks like any background notification converted into a display notification then when the user clicks on the notification it can be handled. @ivk1800 Could you confirm what your approach here is?

@ivk1800
Copy link
Contributor Author

ivk1800 commented Jul 29, 2019

@kroikie my PR resolve problem of "lost data messages". programmer must choose way for handle data message. In example simply displayed notification, but you can chose another way for prevent lost message, for example accumulate their in preferences and handle in dart code after launch application.

@kroikie
Copy link
Contributor

kroikie commented Jul 29, 2019

Would the developer using the background feature have to write their own FlutterBackgroundMessagesReceiver?

@ivk1800
Copy link
Contributor Author

ivk1800 commented Jul 30, 2019

yes, receiver with intent filter

io.flutter.plugins.firebasemessaging.BACKGROUND_NOTIFICATION

@kroikie
Copy link
Contributor

kroikie commented Jul 30, 2019

In #1900 background messages are handled by Dart code defined by the developer without having to write custom native code. I believe that PR covers the use case solved here, would you mind confirming?

@ivk1800
Copy link
Contributor Author

ivk1800 commented Jul 30, 2019

In #1900 background messages are handled by Dart code defined by the developer without having to write custom native code. I believe that PR covers the use case solved here, would you mind confirming?

yes, you right

@kroikie
Copy link
Contributor

kroikie commented Jul 30, 2019

Sounds good, I'll add you as a reviewer on #1900 and close this PR, thanks again for this PR.

@kroikie kroikie closed this Jul 30, 2019
@pafnat
Copy link

pafnat commented Aug 20, 2019

In #1900 background messages are handled by Dart code defined by the developer without having to write custom native code. I believe that PR covers the use case solved here, would you mind confirming?

yes, you right

is there way to retrieve callback on Dart side when app is closed?

@kroikie
Copy link
Contributor

kroikie commented Aug 20, 2019

That may be possible however that would have to be something outside of the firebase_messaging plugin.

@braysonjohn148
Copy link

Although i couldn't understand what exactly is happening here, but this seem cool. Am trying to find a workaround for receiving data message when app is completely terminated. Is it possible..?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants