Not receiving notification - android

We are using parse to store chat messages and we are using notification of parse.
For iOS we are doing this to create entry in installation table of parse.. It's creating entry in installation table of parse, which i think is must to receive notification.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
currentInstallation.deviceToken = user.notificationToken;
[currentInstallation saveInBackground];
But in android I am not able to create entry in installation table.
I am not receiving notification from parse and I think this is the reason behind not getting notification..
Is this the case?
Can any one guild me to the right path ?
UPDATE
Now receiving notification but still having some doubts.
I am doing this when user logs in. I have put conditions if user is not created then only create otherwise don't. I haven't added it to this because that's not necessary
// setting up parse installation
private void setUpParseInstallation()
{
ParseInstallation currentInstallation = ParseInstallation
.getCurrentInstallation();
currentInstallation.saveInBackground(new SaveCallback()
{
#Override
public void done(com.parse.ParseException e)
{
if (e != null)
{
Log.e(TAG, "Error saving parse installation");
}
}
});
}
// add user to parse it it doesn't exist otherwise handle the cases
private void addUserToParseIfNotExisting()
{
// if user doesn't exist create a new user
ParseObject newuser = new ParseObject("user");
newuser.put("name", email);
newuser.put("userId", id);
newuser.saveInBackground();
}
private void setChannel()
{
channel = "abdf";
RS_User user = new RS_User(this);
ParseQuery<ParseObject> pquery = ParseQuery.getQuery("user");
pquery.whereEqualTo("userId", user.getUserId());
// see if user exists in user table on parse
pquery.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done(List<ParseObject> list,
com.parse.ParseException error)
{
if (list.size() > 0)
{
list.get(i).put("channels", channel);
list.get(i).saveInBackground();
PushService.subscribe(getApplicationContext(),channel, RS_HelpActivity.class);
}
}
});
}
Sending a notification
ParsePush push = new ParsePush();
if(object.get(k).has("channels"))
{
push.setChannel(object.get(k).getString(
"channels"));
}
push.setData(dataAndroid);
push.sendInBackground();
Currently I am doing all this to send/receive notification using Parse. Is there a way to do without using channel and directly using notification token or something else using parse ? Because I will be having user notification token.

I hope this code will help you
Application.java
public class Application extends android.app.Application {
public Application() {
}
#Override
public void onCreate() {
super.onCreate();
// Initialize the Parse SDK.
Parse.initialize(this, "your applicationId", "your clientKey");
// Specify an Activity to handle all pushes by default.
PushService.setDefaultPushCallback(this, MainActivity.class);
}
}
AndroidManifest.xml
<application
android:name="<Your Package Name>.Application"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >

Have you tried to use advanced targeting to send a notification to any installation with a device token which matches a contained in (in) query (or any other condition you need).
Something like this:
ParseQuery<ParseInstallation> query = ParseInstallation.getQuery();
query.whereEqualTo("your_key", "your_value");
// OR any of whereXXX method
ParsePush push = new ParsePush();
push.setData(dataAndroid);
push.setQuery(query);
push.sendInBackground();
EDIT
ParseInstallation as others ParseObject(s) has put method.
Since in Android you haven't a UDID like iOS you have to figure out how to create something similiar. Unfortunately I cannot send you how we generate "ours" device token, but here you can find valid suggestions.
ParseInstallation install = ParseInstallation.getCurrentInstallation();
install.put("device-token", yourGeneratedDeviceId);
install.saveInBackground(new SaveCallback() { ... });

Related

How to execute action, in React Native, when notification arrives and the app is in background without the interaction of the user?

I have a React Native app that receives a push notification from my server.
When the app is in background and the user open the notification the app prints a label.
When the app is in foreground and receives the notification the app immediately prints a label.
I would like to print the label without the interaction of the user when the app is in background.
How can I achieve this?
I was thinking to use Expo Background Fetch but I need to print the label immediately after the notification and with the Expo Background Fetch I could print too late.
Thanks
One option can be to print labels from Java using this class which overrides the expo notification service
public class FirebaseMessageService extends FirebaseMessagingService {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//SHOW EXPO NOTIFICATION
createNotificationsHelper().notificationReceived(createNotification(remoteMessage));
//PRINT LABEL IN JAVA...
}
public void sendRegistrationToServer(String token) {
// put your logic here to update fcm registration token
}
protected NotificationsHelper createNotificationsHelper() {
return new NotificationsHelper(this, NotificationsScoper.create(this).createReconstructor());
}
protected Notification createNotification(RemoteMessage remoteMessage) {
String identifier = remoteMessage.getMessageId();
if (identifier == null) {
identifier = UUID.randomUUID().toString();
}
JSONObject payload = new JSONObject(remoteMessage.getData());
NotificationContent content = new JSONNotificationContentBuilder(this).setPayload(payload).build();
NotificationRequest request = createNotificationRequest(identifier, content, new FirebaseNotificationTrigger(remoteMessage));
return new Notification(request, new Date(remoteMessage.getSentTime()));
}
protected NotificationRequest createNotificationRequest(String identifier, NotificationContent content, FirebaseNotificationTrigger notificationTrigger) {
return new NotificationRequest(identifier, content, notificationTrigger);
}
}
and add this in your manifest:
<service
android:name=".FirebaseMessageService"
android:exported="false">
<intent-filter android:priority="-1">
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

Android: Firebase token is null at first run

I am using FCM to provide notifications in my app. Everything worked well, but now I realised that, when I install my application using Android Studio (not from GooglePlay) the token is null at first run. When I close my app and restart it, the token is not null anymore. What cause this problem and how can I avoid it?
InstanceIDService:
public class InstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
registerToken(token);
}
private void registerToken(String token) {
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("Token",token)
.build();
Request request = new Request.Builder()
.url("url_to_registration_script")
.post(body)
.build();
try {
client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In MainActivity:
FirebaseMessaging.getInstance().subscribeToTopic("topic");
String token = FirebaseInstanceId.getInstance().getToken();
Log.d("TOKEN", token);
Last log returns null when app is installed and started for the first time
Registration script:
<?php
if (isset($_POST["Token"])) {
$_uv_Token=$_POST["Token"];
$conn = mysqli_connect("localhost","user","pass","db") or die("Error connecting");
$q="INSERT INTO users (Token) VALUES ( '$_uv_Token') "
." ON DUPLICATE KEY UPDATE Token = '$_uv_Token';";
mysqli_query($conn,$q) or die(mysqli_error($conn));
mysqli_close($conn);
}
?>
The token is fetched asynchronously on first app start. You have to wait for onTokenRefresh() to be called in your FirebaseInstanceIdService before the token can be accessed.
uninstall the app from emulator and run again , so that the onTokenRefreshed method will be called again .
To check wether you are already registered and you just want to know the FCM TOken
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
add the above line in MyFirebaseMessagingService class any where(in oncreate method ) and just Toast or log the refreshedToken.
Just replace:
String token = instanceID.getToken();
with:
String token = instanceID.getToken($SENDER_ID, "FCM");
and it will work.
I was facing the same problem. I looked through a lot of SO posts and other forums and I found a solution that worked for me. FCM documentation says to use this method to get a token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
I found a post online (I apologize, I don't remember which one. I found it a while ago) that used this method instead:
String refreshedToken = FirebaseInstanceId.getInstance().getToken() (String authorizedEntity, String scope);
FCM documentation describes the first method as:
Return the master token for the default Firebase project.
While the second one is described as:
Returns a token that authorizes an Entity to perform an action on behalf of the application identified by Instance ID.
This is similar to an OAuth2 token except, it applies to the application instance instead of a user.
For example, to get a token that can be used to send messages to an application via FirebaseMessaging, set to the sender ID, and set to "FCM".
I have been looking into why the first method call takes a longer time to return a token, but I haven't found an answer yet. Hope this helps.
Even I had the same issue. I had given the Log statement to print token in onCreate of my launcher activity. It takes time to refresh the token once you uninstall the app. Thats why you get null. You have to wait for a bit to get the token refreshed.
Sometimes network issues may occur, even internet is working fine....
check your FirebaseInstancId class defined in Manifest file in your android project.
I just fell in same issue and this is the way I fixed it. Call the block somewhere in onCreate() method of your activity. I want to sent the Token to my Parse server so you must change it based on your needs.
This is the sample I followed.
private void subscribeUserToParse() {
String deviceToken = FirebaseInstanceId.getInstance().getToken();
if (TextUtils.isEmpty(deviceToken)) {
Intent intent = new Intent(this, MyFirebaseInstanceIDService.class);
startService(intent);
return;
}
User user = UserUtil.retrieveUserFromDB(mRealm);
String objectId = user.getParseObjectId();
if (!TextUtils.isEmpty(objectId)) {
ParseUtils.subscribeWithUsersObjectId(objectId, deviceToken);
}
}
The biggest issue i faced after writing the correct code is:-
not the latest version of google play services in build-gradle,
So always use the google-play-services version shown by firebase in setting up dialog
I was having the same problem in a Android 4.2 device.
So, to solve the problem, first, check if your service, in the manifest, if it have a priority like this:
<service
android:name=".other.MyFirebaseInstanceIDService"
android:exported="false">
<intent-filter android:priority="1000">
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Second, use a broadcast intent to notify your MainActivity that changed the token:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
final Intent intent = new Intent("tokenReceiver");
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
intent.putExtra("token",refreshedToken);
broadcastManager.sendBroadcast(intent);
}
Then in MainActivity, in the onCreate, add this:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
LocalBroadcastManager.getInstance(this).registerReceiver(tokenReceiver,
new IntentFilter("tokenReceiver"));
}
and, in the MainActivity, add a new BroadcastReceiver:
BroadcastReceiver tokenReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String token = intent.getStringExtra("token");
if(token != null)
{
Log.e("firebase", String.valueOf(token));
// send token to your server
}
}
};
Since the getToken() method is deprecated, you have to replace it with a listener.
Just replace String token = FirebaseInstanceId.getInstance().getToken(); by the following code snippet:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
// Log and toast
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
You can find the official google documentation here: https://firebase.google.com/docs/cloud-messaging/android/client
And a nice medium post will help you out as well: https://medium.com/#cdmunoz/fcm-getinstance-gettoken-in-android-is-now-deprecated-how-to-fix-it-3922a94f4fa4

Sinch onShouldSendPushData takes few seconds to get fired

I've developed an instant messaging app following these tutorials:
https://www.sinch.com/tutorials/android-messaging-tutorial-using-sinch-and-parse/
and
https://www.sinch.com/tutorials/send-push-notifications-android-messaging-app-using-gcm/
Everything is working fine. From a user phone I've tried to send an instant message to another user in which the MessageService is stopped (on his device). The user gets the notification.
This is the implementation of my method:
#Override
public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {
final WritableMessage writableMessage = new WritableMessage(message.getRecipientIds().get(0), message.getTextBody());
ParseQuery userQuery = ParseUser.getQuery();
userQuery.whereEqualTo("objectId", writableMessage.getRecipientIds().get(0));
ParseQuery pushQuery = ParseInstallation.getQuery();
pushQuery.whereMatchesQuery("idutente", userQuery);
// Send push notification to query
ParsePush push = new ParsePush();
push.setQuery(pushQuery); // Set our Installation query
push.setMessage("sent you a message");
push.sendInBackground(new SendCallback() {
#Override
public void done(ParseException e) {
if(e==null){
}else{
e.printStackTrace();
}
}
});
}
The problem is the following :
if I'm in the MessagingActivity and I'll write a message and I quit the activity before onShouldSendPushData gets called (for instance a write a quick message and then I click to the back button to exit the application) the push notification is never fired (obviously because onShouldSendPushData is not called in time).
Is there a way to wait for onShouldSendPushData to get fired before closing the app? Is there a listener or some property that I can check in order to prevent the closing of the activity before onShouldSendPushData gets called?
Thank you,
Andrea
Not really, you should probably just make a progress indicator, but if you kill the app there is not way for us to now this. One way of implementing this is to have a "Service" pattern in you app that is always running, so instead of handling everything in the MessagingActivity. Then you could continue to run in the background.

Parse Push Notifications Android to appear once the app is opened

I have done a lot of reading on Parse push notifications. I have push notifications working perfectly if the app is running or sitting in the background (user gets out of the app by pushing the home button or back button). I know I cannot get notifications to appear if the app has been force quit but if I close the app/force quit the app, is there a way to get the notifications to pop up the next time the app opens?
I have implemented MainApplication and made sure my manifest is correct but if the app is completely closed, then I do a push notification from Parse and then go to open the app it is as if it has not received it and never will display. Is that normal behavior?
Thanks,
Adam
Main Application
public class MainApplication extends Application {
private static MainApplication instance = new MainApplication();
public MainApplication()
{
instance=this;
}
public static Context getContext()
{
return instance;
}
#Override
public void onCreate() {
super.onCreate();
Parse.enableLocalDatastore(this);
//initialise whatson from parse.com
Parse.initialize(this, "xxxxx", "xxxxx");
PushService.setDefaultPushCallback(this, MainActivity.class);
//to register device to get push notifications and register the install
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}

Parse - Notification not being received

I am trying to send a Parse Push Notification from one Android application to all others.
The following is the set-up code in my Application object:
Parse.enableLocalDatastore(this);
ParseObject.registerSubclass(Game.class);
Parse.initialize(this, "code", "code");
ParsePush.subscribeInBackground(ParseHelper.SUBSCRIPTION_CHANNEL_GAME);
The following is the Push Notification code:
ParsePush push = new ParsePush();
String message = "Hello";
push.setChannel(ParseHelper.SUBSCRIPTION_CHANNEL_GAME);
push.setMessage(message);
push.sendInBackground(new SendCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(CreateGameActivity.this, "Success", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(CreateGameActivity.this, "Failed", Toast.LENGTH_LONG).show();
}
}
});
break;
}
Even though the Success Toast is called, I still don't see the Notification appearing on any of the two Android devices I have installed the app on.
I have tested the Push Notifications via www.parse.com's Dashboard and that does work. Why won't it work in my app though?
To send notifications from a device, you have to do one extra step. Go into the settings of your app on parse and enable Client Push. That should resolve your issue.

Categories

Resources