I have a code snippet here to send a notification from a device to multiple devices:
public static void sendNotificationToUser(final String message) {
Firebase ref = new Firebase("https://danger-alarm.firebaseio.com/");
final Firebase notifications = ref.child("danger-alarm");
Map notification = new HashMap<>();
notification.put("message",message);
notifications.push().setValue(notification);
}
How my Firebase database looks like:
But the problem is, when I execute these codes, it doesn't send anything
Related
I'm making chat application trying to get push notification when new message received to user from another when app is in background using send notifications between Android devices using Firebase Database, Cloud Messaging and Node.js.
I'm following this blog.Here's
[https://firebase.googleblog.com/2016/08/sending-notifications-between-android.html]
and below is my code which I tried.
#Override
public void onClick(View view) {
if (view.getId() == R.id.btnSend) {
String content = editWriteMessage.getText().toString().trim();
if (content.length() > 0) {
editWriteMessage.setText("");
Message newMessage = new Message();
newMessage.text = content;
newMessage.idSender = StaticConfig.UID;
newMessage.idReceiver = roomId;
newMessage.timestamp = System.currentTimeMillis();
FirebaseDatabase.getInstance().getReference().child("message/" + roomId).push().setValue(newMessage);
sendNotificationToUser(newMessage.idReceiver,newMessage.text);
}
}
}
public void sendNotificationToUser(String user, String message) {
Map notification = new HashMap<>();
notification.put("username", user);
notification.put("message", message);
FirebaseDatabase.getInstance().getReference().child("notificationRequests").push().setValue(notification);
}
By using above codes the username and message is getting saved in real time database in notificationRequests.
And I really don't have idea that how can the push notification is received by this line of code.
FirebaseMessaging.getInstance().subscribeToTopic("user_"+username);
And the most important where do i need to put the above code to make it work.
and also I have created the bucket to host my node.js file.
thanks in advance.
EDIT: I misunderstood your problem. Make sure that firebase messaging service is in your manifest.xml file.
Original:
Use the functions.database.ref().onCreate() method. Inside the ref() parameters put the path to your notification requests.
Here's some base code in TypeScript.
export const notificationListener = functions.database
.ref('/NotificationRequests/{notification}').onCreate((snapshot, context) =>
{
try {
admin.initializeApp();
} catch (e) {
}
//Code to send notification here
return admin.database().ref('/NotificationRequests/' + context.params.notification)
}
)
The information you need for the notification is located under snapshot.child('your path here').
See why and how this works
I am setting up a service to send push notifications to our apps using an Azure Notification Hub. Registering the android device works fine (shows up correctly in VS 2015 Azure tools) but when I try and send a test post through the Azure portal or the VS 2015 Test Send tool I get the error "The Push Notification System handle for the registration is invalid" and the registration is deleted. I understand that when the notification hub gets an error it deletes the registration so that part makes sense. I can't find any info on why the PNS would be invalid. My registration code is:
public class PushRegObject
{
public string Platform { get; set; }
public string Handle { get; set; }
public string[] Tags { get; set; }
}
public async static Task<ObjectResultObject<string>> RegisterDevice(PushRegObject reg)
{
string newRegistrationID = null;
var hub = NotificationHubClient.CreateClientFromConnectionString(_connectionstring_, _name_);
if (reg.Handle != null)
{
// Get the Registration ID
var registrations = await hub.GetRegistrationsByChannelAsync(reg.Handle, 100);
foreach(var registration in registrations)
{
if (newRegistrationID == null)
newRegistrationID = registration.RegistrationId;
else
await hub.DeleteRegistrationAsync(registration);
}
if (newRegistrationID == null)
newRegistrationID = await hub.CreateRegistrationIdAsync();
// Register the Device
RegistrationDescription regObj = null;
switch (reg.Platform)
{
case "android":
var regDesc = await hub.CreateGcmNativeRegistrationAsync(newRegistrationID);
return new ObjectResultObject<string>(true, null) { Object = regDesc.GcmRegistrationId };
case "ios":
regObj = new AppleRegistrationDescription(reg.Handle);
break;
default:
return new ObjectResultObject<string>(false, "Unknown device type");
}
}
return new ObjectResultObject<string>(true, null) { Object = newRegistrationID };
}
Any ideas?
Update
With the help of Dmitry in narrowing down the problem, I found the solution which was to use the full token return from GCM in the CreateGcmNativeRegistrationAsync call.
var regDesc = await hub.CreateGcmNativeRegistrationAsync(reg.Handle);
Jason, my name is Dmitry and I work in Notification Hubs team. Below are a few steps that will help us to troubleshoot this issue.
Use NotificationHubClient.GetAllRegistrationsAsync(100) to get all your registrations from the notification hub, find the registration from your test android device there and compare the GcmRegistrationId of this registration with the actual registration id which device recieves from GCM.
If the registration ids on the previous step are equal, then make sure that you uploaded the correct GCM API Key to the notification hub.
If GCM credentials in the notification hub are correct, then try to send a notification to your device using some third-party tools, for example cURL and command line as Google suggests here - https://developers.google.com/web/fundamentals/getting-started/push-notifications/step-07?hl=en. Make sure that you use the same API Key, that was configured in the notification hub, and registration id, that was uploaded into the notification hub.
If you were able to successfully send a notification to your device using a third-party tool, then please send namespace and notification hub name to nhubsupport#microsoft.com and I'll take a look.
Official documentation advises not to use client push notification. Instead cloud push notifications should be used. But does that count as an API call?
CODE:
// WRONG WAY TO SEND PUSH - INSECURE!
ParseQuery pushQuery = ParseInstallation.getQuery();
pushQuery.whereEqualTo("user", userObject);
ParseUser currentUser = ParseUser.getCurrentUser();
String message = currentUser.getString("name") + " says Hi!";
ParsePush push = new ParsePush();
push.setQuery(pushQuery); // Set our Installation query
push.setMessage(message);
push.sendInBackground();
vs (cloud version + missing cloud code):
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("recipientId", userObject.getObjectId());
params.put("message", message);
ParseCloud.callFunctionInBackground("sendPushToUser", params, new FunctionCallback<String>() {
void done(String success, ParseException e) {
if (e == null) {
// Push sent successfully
}
}
});
I mean, if I would have use client push notifications, would that be 1 call per push less? Since parse.com is restricting users on call/s, then it is very important to know.
UPDATE:
The first option, is not right one, it is client push which performs only 1 API call/request.
While second one, just asks ParseCloud to do the push for itself. But that means, it is 2 API calls/requests. Because one is performed by Android app to cloud, and then cloud is doing the actual push. But I just wanted to know if it is really like that.
In Quickblox GCM, when i try to send a message via push to a certain user id, i receive the notification on the sender's device too. I am not sure why, is it the norm in development mode?
QBEvent event = new QBEvent();
event.setUserId(sendToUserId);
event.setType(QBEventType.ONE_SHOT);
event.setEnvironment(QBEnvironment.DEVELOPMENT);
event.setNotificationType(QBNotificationType.PUSH);
event.setPushType(QBPushType.GCM);
HashMap<String, String> data = new HashMap<String, String>();
data.put("data.message", "Message from John");
data.put("data.type", "Notify");
data.put("ParentId",dialogId.toString());
event.setMessage(data);
QBMessages.createEvent(event, new QBEntityCallbackImpl<QBEvent>() {
#Override
public void onSuccess(QBEvent qbEvent, Bundle args) {
System.out.println("GCM Message Sent inside event " );
}
#Override
public void onError(List<String> errors) {
System.out.println("GCM Message ERROR inside event ");
}
});
The above code does send a GCM, but to both devices. The sendToUserId as well as the sender's device.
Am i doing anything wrong?
Actually you don't need to set the user_id field - it comes in a response from server and contains the ID of a sender
Look at Push code sample http://quickblox.com/developers/SimpleSample-messages_users-android#Send_Push_Notifications_from_Application
// recipients
StringifyArrayList<Integer> userIds = new StringifyArrayList<Integer>();
userIds.add(53779);
userIds.add(960);
QBEvent event = new QBEvent();
event.setUserIds(userIds);
So, it should be userIds, not userId
Background
I have an Android app with a working receiver that can receive the push notification sent from iOS device and Parse website.
However, the following cases are not working:
send push notifications from Android to Android
send push notifications from Android to iOS
Since the Android app can receive push notifications without any problems, I guess there must be something with my logic/code of sending the push notifications
Problem Description
When sending push notifications using parsePush.sendInBackground(SendCallback) method, it returns no ParseExceptions. So it means no error.
But the Parse Dashboard does not show this push notifications and the target destination (either iOS or Android device in this case) does not get anything.
In the normal case, when a push notification is sent via Parse, it will show up as a push history in the Dashboard (the working case does that), but when I tried to send pushes from Android device, it just not show anything in the Dashboard and the pushes are never get delivered.
Code
The problematic Android code:
public void onShouldSendPushData(MessageClient messageClient, Message message, List<PushPair> pushPairs) {
//TODO setup offline push notification
Log.d(TAG, "Recipient not online. Should notify recipient using push");
if (pushPairs.size() > 0 && !chatRecipient.isEmpty()) {
PushPair pp = pushPairs.get(0);
String pushPayload = pp.getPushPayload();
ParsePush parsePush = new ParsePush();
ParseQuery query = ParseInstallation.getQuery();
ParseQuery userQuery = ParseUser.getQuery();
userQuery.whereEqualTo("username", chatRecipient);
query.whereMatchesQuery("user", userQuery);
parsePush.setQuery(query);
// JSON object for android push
String alertString = getResources().getString(R.string.push_notification_msg);
try {
JSONObject data = new JSONObject();
data.put("alert", String.format(alertString, chatRecipient));
data.put("badge", "Increment");
data.put("sound", "default");
// pass the sender name as "title"
data.put("title", ParseUser.getCurrentUser().getUsername());
data.put("uri", "");
data.put("SIN", pushPayload);
parsePush.setData(data);
parsePush.sendInBackground(new SendCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i(TAG, String.format("Push notification to %s sent successfully", chatRecipient));
} else {
Log.e(TAG, String.format("Private chat push notification sending error: %s", e.getMessage()));
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
The working iOS code:
- (void)message:(id<SINMessage>)message shouldSendPushNotifications:(NSArray *)pushPairs {
// use parse to send notifications
// send notifications
NSLog(#"Recipient not online. Should notify recipient using push");
if (pushPairs.count > 0 && userSelected != nil) {
pushData = [[pushPairs objectAtIndex:0] pushData];
pushPayload = [[pushPairs objectAtIndex:0] pushPayload];
PFPush *push = [[PFPush alloc] init];
PFQuery *query = [PFInstallation query];
PFQuery *userQuery = [PFUser query];
[userQuery whereKey:#"username" equalTo:userSelected];
[query whereKey:#"user" matchesQuery:userQuery];
[push setQuery:query];
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:#"You have a new Message from %#", [PFUser currentUser].username], #"alert",
#"Increment", #"badge",
#"default", #"sound",
pushPayload, #"SIN",
nil];
[push setData:data];
[push sendPushInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Push notification to %# sent successfully.", userSelected);
} else {
NSLog(#"push notifications sending error: %#", error);
}
}];
} else {
NSLog(#"Error: No push pairs.");
}
Note
I can confirm that the code above is getting called each time I want to send push notifications, and no exceptions are returned. I can also confirm that the data packaged inside the push is not null.
I'm not posting the receiver's code as that part of code is working and should do nothing with this issue.
The iOS code and Android code basically are the same, why the sending pushes function in Android not working?
UPDATE
I upgraded Parse SDK to 1.8.2, with its Logging options set to VERBOSE and still can't find any clue why the Push notifications are not sent.
I even made a simple project out of the Parse example project with only Login and send message functions and its sending message function is still not working. So frustrating.
I have found the reason.
It is the "uri" field inside JSON.
As long as this field is included (with or without the content), notifications seemed being ignored by Parse, although you'll get a non-error callback.
If you remove "uri" field inside your JSON, notifications will become normal.
I've reported this bug to Parse and they've started to solve it.
Update
According to the reply from Parse.com, this is an intended feature, so the notifications with "uri" field will be discarded on the server side, thus it will not be sent.
related link:
https://developers.facebook.com/bugs/338005256408244