I'm trying to find out how to push proper notifications using Codename One servers. I'd like to send notifications which basically look like LocalNotifications - with title, body, badge etc.
However in the documentation for push servers there seems to be just one field concerning the notification payload:
body - the body of the message.
Q1: How to push(server side through Codename One server) and display(Codename One app) a notification with title and body from the server?
I'd like be able to send and receive custom data in the payload too, e.g. reference to some app content which should be opened in the app when opening the app "from" that particular push notification.
Q2: Can I send basically anything as a notification body, even my own JSON?
In the Codename One API there is this callback interface PushCallback, specifically method void push(String value). Is this callback intended exactly for the purpose of "pre-processing/parsing" of the notification payload just before displaying it as a LocalNotification?
Thanks.
There are various types of push messages you can send in Codename One, namely 0,1,2,3,4,5,100, and 101.
If you require the title and the body, set your push type to 4 and separate your title and body with ; in your payload.
If you require a push with some hidden content which you can use to manipulate your app in the background, go for push type 3. Separate the visible and hidden payloads with ;. The hidden section is where you put your JSON string, just ensure the vissible message doesn't start with { or [. A php payload example will look something like this:
$vissibleMsg = "Cum ut quia delectus libero hic.";
$jsonString = json_encode(array("action" => "openMainForm", "id" => "1", "message" => $vissibleMsg));
$payload = $vissibleMsg . ";" . $jsonString;
And in your push(String value), read the hidden JSON content like this:
#Override
public void push(String value) {
Display.getInstance().callSerially(() -> {
if (value.startsWith("{") || value.startsWith("[")) {
try {
JSONObject response = new JSONObject(value);
switch (response.getString("action")) {
case "openMainForm":
//do whatever you want here
break;
default:
//perform default action here
break;
}
} catch (JSONException err) {
Log.e(err);
}
}
});
}
If you require a hidden content and a visible content with title and body, then you will have to send the push twice using type 2 and type 4 respectively, based on the link I shared above.
Related
I am thinking about keeping all registration ids(push token) in DB and sending notifications to user from iPhone. I tried something like this but did not get any notification.
func sendPNMessage() {
FIRMessaging.messaging().sendMessage(
["body": "hey"],
to: TOKEN_ID,
withMessageID: "1",
timeToLive: 108)
}
What I am doing wrong or maybe it is impossible at all?
Currently it's not possible to send messages from the application itself.
You can send messages from the Firebase Web Console, or from a custom server using the server-side APIs.
What you might want to do is to contact a server (like via http call) and that server will send the message to the user.
This way ensure that the API-KEY of the server is protected.
PS: the sendMessage(..) api is called upstream feature, and can be used to send messages from your app to your server, if you server has an XMPP connection with the FCM server.
Yes you can send push notification through Firebase.Please make sure do NOT include the server-key into your client. There are ways "for not so great people" to find it and do stuff... The Proper way to achieve that is for your client to instruct your app-server to send the notification.
You have to send a HTTP-Post to the Google-API-Endpoint.
You need the following headers:
Content-Type: application/json
Authorization: key={your_server_key}
You can obtain your server key within in the Firebase-Project.
HTTP-Post-Content: Sample
{
"notification": {
"title": "Notification Title",
"text": "The Text of the notification."
},
"project_id": "<your firebase-project-id",
"to":"the specific client-device-id"
}
Google Cloud Functions make it now possible send push notifications from device-to-device without an app server.
From the Google Cloud Functions documentation:
Developers can use Cloud Functions to keep users engaged and up to
date with relevant information about an app. Consider, for example, an
app that allows users to follow one another's activities in the app.
In such an app, a function triggered by Realtime Database writes to
store new followers could create Firebase Cloud Messaging (FCM)
notifications to let the appropriate users know that they have gained
new followers.
Example:
The function triggers on writes to the Realtime Database path where followers are stored.
The function composes a message to send via FCM.
FCM sends the notification message to the user's device.
Here is a demo project for sending device-to-device push notifications with Firebase and Google Cloud Functions.
Diego's answer is very accurate but there's also cloud functions from firebase it's very convenient to send notifications in every change in the db. For example let's say you're building chat application and sending notification in every new follower change.
This function sample is very good example.
For more information about cloud functions you can check official docs.
I have an app that has a "send feedback to developer" section. I also have a User collection in my firestore database. When a user logs into the app, I have that Users data update their FCM token with the following code in my SceneDelegate.swift:
import Firebase
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
authListener = Auth.auth().addStateDidChangeListener({ (auth, user) in
Auth.auth().removeStateDidChangeListener(self.authListener!)
if user != nil {
DispatchQueue.main.async {
let docRef = Firestore.firestore().collection("User").document((user?.email)!)
docRef.getDocument { (snapshot, error) in
guard let snapshot = snapshot else {return}
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
docRef.updateData(["FCMtoken":token])
print("FCM registration token: \(token)")
}
}
}
}
}
})
guard let _ = (scene as? UIWindowScene) else { return }
}
then in my feedback view controller i have this code to send my specific device (but you can look up/fetch which specific device you want in your database where the FCMtoken is stored where i have INSERT-DEVICE-TOKEN-HERE). The url to send to is "https://fcm.googleapis.com/fcm/send" and you can find YOUR-APP-FCM-KEY by going to your project settings in firebase, going to cloud messaging tab and its the server key.
func sendMePushNotification() {
let token = "INSERT-DEVICE-TOKEN-HERE"
if let url = URL(string: "https://fcm.googleapis.com/fcm/send") {
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Content-Type":"application/json", "Authorization":"key=YOUR-APP-FCM-KEY"]
request.httpMethod = "POST"
request.httpBody = "{\"to\":\"\(token)\",\"notification\":{\"title\":\"Feedback Sent!\",\"body\":\"\(self.feedbackBox.text!)\",\"sound\":\"default\",\"badge\":\"1\"},\"data\": {\"customDataKey\": \"customDataValue\"}}".data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, urlresponse, error) in
if error != nil {
print("error")
} else {
print("Successfully sent!.....")
}
}.resume()
}
}
Use onesignal,you can send device to notifications or device to segments ,it can work with firebase in this way
Use onesignal functions to create a specific id,save it in a firebase database ,then when the id can be put in another function that is used to send a notification
Notes: 1-i am using it in my apps with firebase works perfectly
2-i can submit that code,just someone comments so i can find this answer
Has anyone created an open source project that exposes the facebook messenger bot API in java? (or another language I could convert?)
Essentially an object hierarchy for the stack found in:
https://developers.facebook.com/docs/messenger-platform/send-api-reference
I'd rather not just use JsonObjects, etc. nor Maps to extract the incoming JSON chat messages or to build the outgoing structured chat replies. If an open source project for this exists -- I have not found it.
Take a look at FaceBot. The goal of FaceBot is making the Facebook's Messenger Platform easier: with FaceBot, you only need less than 5 lines of code to set up your own Messenger bot.
Here's an example:
public class MyFaceBotBehavior extends AbstractFaceBot {
public void defineBehavior() {
// Setting my tokens from Facebook (page token and validation token for webhook).
FaceBotContext.getInstance().setup("myFacebookPageToken", "myFacebookWebhookValidationToken");
// Defining a bot which will reply with "Hello World!" as soon as I write "Hi"
addActionFrame(new MessageEvent("Hi"),
new MessageAutoReply("Hello World!"));
}
}
If you have questions or need help, feel free to contact me (I'm the developer).
With the open source project messenger4j you will get all you need.
It's an easy to use Java library for building chatbots on the Messenger Platform.
It provides a rich builder API to construct the outgoing messages.
Furthermore it parses the inbound messages to specific java objects and automatically detects their type. For each message type or event you can register corresponding event handlers.
Receiving:
String payload = ... // callback request body
String signature = ... // 'X-Hub-Signature' request header
// JDK 8 version
MessengerReceiveClient receiveClient = MessengerPlatform.newReceiveClientBuilder("APP_SECRET", "VERIFICATION_TOKEN")
.onTextMessageEvent(event -> System.out.printf("%s: %s", event.getSender().getId(), event.getText()))
.build();
// JDK 7 version
MessengerReceiveClient receiveClient = MessengerPlatform.newReceiveClientBuilder("APP_SECRET", "VERIFICATION_TOKEN")
.onTextMessageEvent(new TextMessageEventHandler() {
#Override
public void handle(TextMessageEvent event) {
System.out.printf("%s: %s", event.getSender().getId(), event.getText());
}
})
.build();
receiveClient.processCallbackPayload(payload, signature);
Sending (simple):
MessengerSendClient sendClient = MessengerPlatform.newSendClientBuilder("PAGE_ACCESS_TOKEN").build();
sendClient.sendTextMessage("RECIPIENT_ID", "Hi there, how are you today?");
Sending (complex):
ReceiptTemplate receipt = ReceiptTemplate.newBuilder("Stephane Crozatier", "12345678902", "USD", "Visa 2345")
.orderUrl("http://petersapparel.parseapp.com/order?order_id=123456")
.timestamp(1428444852L)
.addElements()
.addElement("Classic White T-Shirt", 50F)
.subtitle("100% Soft and Luxurious Cotton")
.quantity(2)
.currency("USD")
.imageUrl("http://petersapparel.parseapp.com/img/whiteshirt.png")
.toList()
.addElement("Classic Gray T-Shirt", 25F)
.subtitle("100% Soft and Luxurious Cotton")
.quantity(1)
.currency("USD")
.imageUrl("http://petersapparel.parseapp.com/img/grayshirt.png")
.toList()
.done()
.addAddress("1 Hacker Way", "Menlo Park", "94025", "CA", "US").street2("").done()
.addSummary(56.14F).subtotal(75.00F).shippingCost(4.95F).totalTax(6.19F).done()
.addAdjustments()
.addAdjustment()
.name("New Customer Discount")
.amount(20.00F)
.toList()
.addAdjustment()
.name("$10 Off Coupon")
.amount(10.00F)
.toList()
.done()
.build();
sendClient.sendTemplate("RECIPIENT_ID", receipt);
BTW: I've built it.
I am currently working on a bot framework in java called JBot and the fb portion is currently under development but the Slack part is done and is used by several developers already.
I'm trying to use Azure mobile services to send push notifications. I got it working but currently it sends to all devices that use the application key. I realise that in the gcm.push.send() function I have to give a tag instead of null if i want to send it to individuals or groups.
I want to send it only to the current user. The user who calls the insert. I tried putting in the users gcm registration id but this does not work.
I saw examples of people registering their tags like this (in push->edit script):
exports.register = function (registration, registrationContext, done) {
var userId = registrationContext.user.userId;
registration.tags.push(userId);
done();
};
However im not using authentication so my user variable is undefined. All ive got is a unique identifier in my item table (item.id) and the registration id (item.regid). How can I get my tag working? This is my insert :
function insert(item, user, request) {
console.log("Registration ID -> " + item.regid);
var payload = {
"data": {
"message": "notification added"
}
};
request.execute({
success: function() {
// If the insert succeeds, send a notification.
push.gcm.send(item.regid, payload, {
success: function(pushResponse) {
console.log("Sent push:", pushResponse, payload);
request.respond();
},
error: function (pushResponse) {
console.log("Error Sending push:", pushResponse);
request.respond(500, { error: pushResponse });
}
});
},
error: function(err) {
console.log("request.execute error", err)
request.respond();
}
});
}
Notification Hubs does not have the ability to send to a specific device right now.
The mechanism for simulate this is through the registration process and tags. Use the Notification Hubs API directly. When you register a device, register to listen with a tag that is appropriate to the device or user. For example, register to listen to tags USER-userid and DEVICE-deviceid.
Then, when you want to send to a specific device, send to DEVICE-deviceid and if you want to send to all devices that are registered to a specific user, you can send to USER-userid; obviously, replace the userid and deviceid with the appropriate values.
You can find out more about tags here: https://msdn.microsoft.com/library/azure/dn530749.aspx
If you want to send notification to specific user you must register them with unique tag or unique identifier as Adrian hall in previous answer described,I agree with him.As unique identifier in Android you can use DeviceId and in Ios identifierForVendor they are unique and they never change.
I need to upload multiple files from jsp. I am using $ajaxFileUPload.js to take the file to server side. I am doing my file size validation in server side for each file. I need a message on validating the file, where i face a problem. I am not able to show that message. Could someone help me in this please?
I have not used the plugin but what I have done previously in similar situation is send different markers back to the client side like for an upload the exceeds the file limit size, you can start the response back with something like 'ERROR:' and then look for this marker in the function getting the response back and then branch to a different logic. You obviously have to parse the response and look for the marker.
Looking quickly at the plugin in Github, it looks like the usage is
$('input[type="file"]').ajaxfileupload({
'action': '/upload.php',
'params': {
'extra': 'info'
},
'onComplete': function(response) {
console.log('custom handler for file:');
alert(JSON.stringify(response));
},
'onStart': function() {
if(weWantedTo) return false; // cancels upload
},
'onCancel': function() {
console.log('no file selected');
}
});
So what I think you can do is in the onComplete function something like
if (response.search("ERROR:") != -1){
//error condition
//add your msg for the front end here
} else {
//non error condition, continue with your regular flow
}
Does this make sense and relate to what you are trying to do?
I want to debug GCM messages which receives my application but the problem I can't log fields outside the data array: collapse key, time-to-live , etc. GCM message which comes from the server is look like this:
{
"registration_ids" : ["xyz"],
"data" : {
text: {...}
},
"time_to_live" : 3
},
For debugging purposes i want to log time-to live parameters and others.But when I do this: String text = intent.getExtras().getString("text"); I can only view what is inside data. How can I view all the GCM message structure?
I don't believe you can.
The parameters outside of data are not part of the notification payload. It's quite reasonable to believe that they are not even passed by the GCM server to your application. These outside params' only purpose is to tell the GCM server how to deliver the message (whether to send it to an idle device, how long to keep it in the GCM server when the device is not available, whether to override older undelivered messages that have the same collapse key, etc...).
EDIT :
Handling Received Data
The com.google.android.c2dm.intent.RECEIVE intent is used by GCM to deliver the messages sent by the 3rd-party server to the application running in the device. If the server included key-pair values in the data parameter, they are available as extras in this intent, with the keys being the extra names. GCM also includes an extra called from which contains the sender ID as an string, and another called collapse_key containing the collapse key (when in use).
From this quote, it seems you can also retrieve the collapse_key and the sender ID in addition to the key/value pairs inside data.