Skip to content

Push notification implementation in Flutter Parse SDK? #302

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

Closed
guilhermedaldim opened this issue Jan 22, 2020 · 17 comments
Closed

Push notification implementation in Flutter Parse SDK? #302

guilhermedaldim opened this issue Jan 22, 2020 · 17 comments

Comments

@guilhermedaldim
Copy link

Is it possible with the Flutter Parse SDK to send push notification?

Send a notification to a specific user with deviceToken and be able to handle it according to the notification payload?

In advance, thank you.

@pastordee
Copy link
Contributor

I use firebase admin on the server side and then use cloud code to send a notification

@guilhermedaldim
Copy link
Author

I can send and receive notifications with firebase admin, thanks @pastordee.

However, on android, when I get notifications in the foreground, the application crashes.

How did you set up your client application?

@pastordee
Copy link
Contributor

pastordee commented Mar 14, 2020

I can send and receive notifications with firebase admin, thanks @pastordee.

However, on android, when I get notifications in the foreground, the application crashes.

How did you set up your client application?

` void configNotification() {
print("onMessage: Initialization ");
var android = new AndroidInitializationSettings('@drawable/ic_notifications');
var ios = new IOSInitializationSettings();
var platform = new InitializationSettings(android, ios);
flutterLocalNotificationsPlugin.initialize(platform);
// _firebaseMessaging.subscribeToTopic('all');

_firebaseMessaging.getToken().then((String token) {
    assert(token != null);
    updateParseInstallation(token);
  });

 _firebaseMessaging.requestNotificationPermissions(
    const IosNotificationSettings(sound: true, badge: true, alert: true)
  );
_firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
    print("Settings registered: $settings");
  });



_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print("onMessage: $message");
    onMessageNotificationsAlert(message);
    
  },
  onLaunch: (Map<String, dynamic> message) async {
    print("onLaunch: $message");
    onLaunchNotificationsAlert(message); 
  },
  onResume: (Map<String, dynamic> message) async {
    print("onResume: $message");
    onResumeNotificationsAlert(message);
  },
);

}
`

e.g
`onMessageNotificationsAlert(Map<String, dynamic> message) async{
print("onMessageNotificationsAlert");

    Map notification = message['notification'];
    var body = notification['body'];
    var title = notification['title'];
    var view = notification['view'];
    var objectId = notification['objectId'];

}`

@pamarcan
Copy link

Thanks pastordee, how did you integrate firebase admin with parse server users?

It would be very useful for everyone to have a solution to send push notifications easily from the parse server.

@RodrigoSMarques
Copy link
Contributor

Hi @pamarcan
I am using OneSignal.
I associate the OneSignal user with the user's ObjectID on the Parse Server.
Using Cloud Code I send Push by activating the OneSignal API.

@pastordee
Copy link
Contributor

pastordee commented Apr 10, 2020

@pamarcan

  1. npm firebase admin

  2. in my main.js in the cloud folder
    var admin = require("firebase-admin"); var serviceAccount = require("/path-to-/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://***********.firebaseio.com" });

                `
                   var options = {
     		priority: "high",
     		timeToLive: 60 * 60 * 24
     	};
     	var payloadIOS ={
     		
     		notification: {
     			title: title,
     			body: theMessage,
     			view: "woeGroup",
     			objectId: post.id
     		}
     		
     	};
     	var payloadAndroid ={
     		
     		notification: {
     			title: title,
     			body: theMessage,
     			view: "woeGroup",
     			objectId: post.id
     		}
     		
     	};
    

`

       `
        var pushQueryFCM = new Parse.Query(Parse.Installation);
    pushQueryFCM.notEqualTo('userId', user.id);// the user posting is not in the channels
    pushQueryFCM.equalTo('channels', publicId);
        pushQueryFCM.find({useMasterKey:true})
		.then((pushQuery) => {
			
			for (i = 0; i < pushQuery.length; i++) {
				
				var deviceType =  pushQuery[i].get('deviceType');
				var token = pushQuery[i].get('deviceToken');
				
				if(deviceType == "ios" && token != ""){
					
					admin.messaging().sendToDevice(token, payloadIOS,options)
					.then(function(response){
						console.log("messaging=>**********successfully" + response);
					})
					.catch(function(error){
						console.log("messaging=>********** Got an error " + error.code + " : " + error.message);
					});
					
					
				}else if(deviceType == "android" && token != ""){
					
					admin.messaging().sendToDevice(token, payloadAndroid,options)
					.then(function(response){
						console.log("messaging=>**********successfully" + response);
					})
					.catch(function(error){
						console.log("messaging=>********** Got an error " + error.code + " : " + error.message);
					});


					
				}//
				
								
			}
		})
		.catch(function(error){
			console.log("messaging=>********** Got an error  pushQueryFCM " + error.code + " : " + error.message);
		});

`

  1. In your pubspec.yaml
    firebase_messaging
    flutter_local_notifications

  2. main.dart
    FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
    FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

    `
    void configNotification() {
    print("onMessage: Initialization ");
    var android = new AndroidInitializationSettings('@drawable/ic_notifications');
    var ios = new IOSInitializationSettings();
    var platform = new InitializationSettings(android, ios);
    flutterLocalNotificationsPlugin.initialize(platform);

    _firebaseMessaging.getToken().then((String token) {
    assert(token != null);
    updateParseInstallation(token);
    });

    _firebaseMessaging.requestNotificationPermissions(
    const IosNotificationSettings(sound: true, badge: true, alert: true)
    );
    _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
    print("Settings registered: $settings");
    });

    _firebaseMessaging.configure(
    onMessage: (Map<String, dynamic> message) async {
    print("onMessageNotificationsAlert $message");
    onMessageNotificationsAlert(message);

    },
    onLaunch: (Map<String, dynamic> message) async {
    onLaunchNotificationsAlert(message);
    },
    onResume: (Map<String, dynamic> message) async {
    onResumeNotificationsAlert(message);
    },
    );

}

Future updateParseInstallation(token) async{

print("updateParseInstallationt $token");
var installation = await ParseInstallation.currentInstallation();
installation.set("deviceToken", token);
var apiResponse = await installation.save();
if(apiResponse.success){
print("updateParseInstallationt initInstallation updated ${apiResponse.result}");
}
}

`

@pamarcan
Copy link

Wow! thanks a lot pastordee

@GursheeshSingh
Copy link
Contributor

I don't think local messaging is needed, only in case you want to show user a notification if app is opened and in foreground.
Firebase messaging does not display notification if app is opened and in foreground.

@pastordee
Copy link
Contributor

pastordee commented Apr 21, 2020

I don't think local messaging is needed, only in case you want to show user a notification if app is opened and in foreground.
Firebase messaging does not display notification if app is opened and in foreground.

Because firebase doesn’t display notification in app that’s why you need something like Flushbar so you can use that to show the in app message yourself

@GursheeshSingh
Copy link
Contributor

Firebase does show notifications.

As explained in their official documentation-
https://pub.dev/packages/firebase_messaging#receiving-messages

If app is in foreground, it doesn't show notifications.

@MungaraJay
Copy link

Hello @phillwiggins @RodrigoSMarques @RodrigoSMarques @guilhermedaldim @pamarcan

Is there any updates related to push notifications with parse sdk in flutter?

Can we implement push notifications using parse server sdk for flutter as well?

Waiting for reply.

Thanks.

@RodrigoSMarques
Copy link
Contributor

@MungaraJay
To use the native functionality it is necessary to use Platform Channel and I do not see the need.
Use Firebase Cloud Messaging that has the plugin ready and does the same.
Retrieve the Token from the device with FCM, save the token in Class Installation.
Send Push Notification through Parse and receive it on the device through FCM.

@vinnytwice
Copy link

vinnytwice commented Nov 2, 2020

To use the native functionality it is necessary to use Platform Channel and I do not see the need.

@RodrigoSMarques
Basically EU companies can't send anything at all to USA..so for push notifications I'd have to avoid FCM altogether.
I'm in the middle of moving away from Firebase as GDPR is very restrictive about UE data sent abroad.
I see you're using OneSignal, are you UE based?
Parse seems to offer all I'm currently using for my app and I can host a Parse server on UE Server providers..

Thanks.

@fischerscode
Copy link
Contributor

@vinnytwice
As far as I know, OneSignal uses FCM in the background. But I might be wrong.

@RodrigoSMarques
Copy link
Contributor

We are closing issues that have been open for a long time without activity.
This will make it easier to organize things from now on.
If the problem persists, please open a new issue.
Thanks.

@gadgetreviews
Copy link

gadgetreviews commented May 19, 2022

I am not sure if the information at this issue is obsolete or not but I am able to send push notification at android without need of firebase admin, just only with parse server. But on iOS, it is not working. I get following error on parse server error log.

ERR! parse-server-push-adapter APNS APNS error transmitting to device <token> with status 400 and reason BadDeviceToken

As far as I understand I need to add some code to AppDelegate.swift at iOS code of flutter. When I added the code to AppDelegate.swift as described in this link, I get compile errors. I think this document needed to be updated. This document might be created for an older version of XCode and/or Swift.

https://docs.parseplatform.org/tutorials/ios-push-notifications/

@Nidal-Bakir
Copy link
Member

Nidal-Bakir commented Jun 7, 2022

@pastordee
I was talking with the back4app support team and they told me the following:
NOTE: I did not try this solution yet but will in a few days (on android) and return here to write about it and edit this comment.
Edit: yes it's working but it will send (Data) type of notifications

At the moment, we do not have a guide for it, but, you can try using the following plugin:

https://pub.dev/packages/firebase_messaging

You can also use this code as a reference to save the device token:

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
void configNotification() {
   var android = AndroidInitializationSettings(‘mipmap/ic_launcher’);
   var ios = IOSInitializationSettings();
   var platform = InitializationSettings(android, ios);
   flutterLocalNotificationsPlugin.initialize(platform);
   _firebaseMessaging.configure(
     onMessage: (Map<String, dynamic> message) async {
       print(“onMessage: $message”);
       showNotification(message);
     },
     onLaunch: (Map<String, dynamic> message) async {
       print(“onLaunch: $message”);
     },
     onResume: (Map<String, dynamic> message) async {
       print(“onResume: $message”);
     },
   );
   _firebaseMessaging.requestNotificationPermissions(
       const IosNotificationSettings(sound: true, badge: true, alert: true));
   _firebaseMessaging.onIosSettingsRegistered
       .listen((IosNotificationSettings settings) {
     print(“Settings registered: $settings”);
   });
   _firebaseMessaging.getToken().then((String token) {
     assert(token != null);
     final ParseInstallation instalattion = await ParseInstallation.currentInstallation ();
     instalation.deviceToken = token;
     await installation.save ();
   });
 }
 showNotification(Map<String, dynamic> msg) async {
   var data = jsonDecode(msg[“data”][“data”]);
   var android = AndroidNotificationDetails(
     ‘aaaaaaaa’,
     “yyyyyyyyyyy”,
     “Yyyyyyyyyyyyyyy”,
   );
   var iOS = IOSNotificationDetails();
   var platform = NotificationDetails(android, iOS);
   await flutterLocalNotificationsPlugin.show(
       0, data[“Title”], data[“alert”], platform);
 }

You have to call the configNotification method inside the flutter view. You will collect the token using the initState() method.

After, to send the push you can use Cloud Code.

This is a Cloud Code function that you can use as a reference:

Parse.Cloud.define("sendPush", function (request, response) {
const userId = request.params.userId;
const title = request.params.title;
const message = request.params.message;
sendPush(userId, title, message);
response.success();
});
function sendPush(user, title, message) {
   var oneWeekAway = new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000);
// Find devices associated with the recipient user
var destinationUser = new Parse.User();
destinationUser.id  = user;
var userQuery = new Parse.Query(Parse.User).get(destinationUser);
const payloadData = {
  "alert": message,
  "title": title,
  "badge": "Increment",
  "sound": "default",
};
console.log('Push Title / Message: ' + title + " / " + message);
var queryInstall = new Parse.Query(Parse.Installation);
queryInstall.matchesQuery("user", userQuery);
// Send the push notification to results of the query
Parse.Push.send({
  where: queryInstall,
  expiration_time: oneWeekAway,
  data: payloadData,
  notification: payloadNotification
}, {
    useMasterKey: true,
    success: function () {
      // Push was successful
      console.log('Push was sent successfully.');
      return true;
    },
    error: function (error) {
      // Push was unsucessful
      console.log('Push failed to send with error: ' + error.message);
      return false;
    }
  });
}

But you can also use the dashboard instead of the Cloud Code function. Follow the initial steps provided in order to set up the push, and then try to use the dashboard for this.

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

No branches or pull requests

10 participants