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
Related
I implemented my backend service (using java and FCM) to send push-notifications to mobile apps.
I implemented my service using Java Firebase Admin-SDK (https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/messaging/package-summary and https://firebase.google.com/docs/cloud-messaging/send-message#java) about this and I'm able to send (and receive) push notifications on iOS and Android mobile apps.
Now I received a request from mobile-developers that they needs to customize (client-side) the received push notifications (also when the app is in background mode).
Probably here is reported a same question: What is the difference between Firebase push-notifications and FCM messages?
Reading the documentation (https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages) I understood that It's necessary to use a Data-message instead of a Notification message.
It's not clear for me what's necessary to change to support this delivery type.
Do I change the Android-config of the FCM-message or Do I remove some unnecessary data (just set all info into the custom data without others info for example Android configuration etc..)
It's possible to have a small example?
If your json will have notification key, developers will not able to handle notifications in background. They will receive this notification only when app is in foreground. In case when developers should receive “silent pushes” or they need control all notifications, you should remove notification key, and use only data key.
This can be achieved by changing the key 'notification' to 'data' as follows:
{
"notification": { //replace this line by "data"
"title": "Hey Gajanan",
"body": "Thanks for visiting omnidecoder.com"
},
"to" : "YOUR-GENERATED-TOKEN"
}
i do not get any notification from firebase but when i test with Pusher app i get the notification.
these are my steps i have Done. help me if i have done something wrong.
1_ add notificationService as below.
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: #escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
bestAttemptContent.title = "hello"
bestAttemptContent.body = "this is test"
contentHandler(bestAttemptContent)
}
}
}
2 _ set notificationCenter delegate to self in app delegate
Messaging.messaging().delegate=self
UNUserNotificationCenter.current().delegate = self
3_ device token for sending notification (i store this to server)
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
i send this FCMToken to server Side(java,spring boot)
4_ i have enabled push notification in Capabilities
5_ i have added .p12 file in cloud messaging of project settings in firebase console but i have big question for this !???? should i login to firebase with my server's account ? or make an account for my self ?? because i have created one for my self.
some tips :
we are a team like server side(JAVA). web , android and ios
which this push notification is working on android but not on ios.
i think i'm doing something in a wrong way.
thank you for reading this topic and helping me out.
Here is the steps to cross check your issue,
Notification Capabilities has to be enabled.
Certificate you created on apple member center should enable the push
notification
In firebase console go to settings -> project settings -> cloud messaging -> check the server key
This key and the key what you gave to you server team should be same
Check APNs Authentication Key or APNs Certificates added or not.
If you are using APNs Certificates, that should be same that you generated in the appId in the member center
get the fcm token from the xcode console -> go to firebase console -> grow -> cloud messaging -> new notification
-> and try test on device. if you receive notification client side (device) has no issues. if not server side has to double check the server key.
Add your googleServiceInfo.plist to your project. add the reversed key in your app info.
in Appdelegate, configure your firebase
FirebaseApp.configure()
Update, As per your question in the comment, am updating this question.
To make use of NotificationService Extension, you notification must include mutable-content property in the notification payload. using fcm api you can do that. put these in the post man,
https://fcm.googleapis.com/fcm/send
in the headers, add your server key (you can get this from your firebase console)
in the body add this payload to fire notification. this will trigger your Notification Service Extension.
{
"notification": {
"title": "1",
"body": "",
"click_action": "",
"icon": "",
"mutable_content": true,
"content_available": true
},
"registration_ids":["add your fcm token"],
"data": {}
}
As per the tutorial:
https://code.tutsplus.com/tutorials/ios-10-notification-service-extensions--cms-27550
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 am very new to java server side development, i have followed this link [http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/][1] and successfully implemented GCM with my android device, the problem is dont know how to trigger the GCM server while the content is updated in my db,i need to notify each and every update of my db to the user, am i need to watch the db using timer task something like that or is there any default solution to keep track of db ?
My Server side code :
regId = "my registration id";
String userMessage = request.getParameter("message");
Sender sender = new Sender(GOOGLE_SERVER_KEY);
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY, userMessage).build();
result = sender.send(message, regId, 1);
have tried with many solution but till now not getting exact solution, Suggestion, ideas or related links are most welcome
Thanks in advance
Without knowing the specific functionality of your server and app, I can only offer a general solution.
Each process in your server that performs DB updates that have to be pushed to some Android devices via GCM can write the messages and the registration IDs to some kind of queue.
Then you can have another process (or processes) that would consume the queue of GCM messages, and send them to Google. These processes can handle failures (retry sending the messages in case of temporary failures), and update your database of registration IDs if they receive responses with canonical registration IDs or errors such as InvalidRegistration or NotRegistered.
I am using Google App Engine in Java to send XMPP messages.
I would like to know if there is a way to check if a user is logged in to the system or logged out. So, when the user signs in, I would like to send him a welcome chat message and when he signs out I would like to notify my server code of the same.
I have tried the presence API but no luck so far.
Assuming you're referring to querying a user's presence via XMPP, keep in mind that this will only work if your App Engine account is authorized by that user. If you have already got that far, querying for presence (user logged in/logged out) is quite simple (source).
If a Google talk user has subscribed to an app (has accepted an invitation or has invited the app to chat), the app can discover the user's availability by looking for a POST to /_ah/xmpp/presence/available. If the user is subscribed and available, you can send them your application's presence and status:
// In the handler for _ah/xmpp/presence/available
XMPPService xmppService = XMPPServiceFactory.getXMPPService();
Presence presence = xmppService.parsePresence(req);
// Split the XMPP address (e.g., user#gmail.com)
// from the resource (e.g., gmail.CD6EBC4A)
String from = presence.getFromJid().getId().split("/")[0];
// Mirror the contact's presence back to them
xmppService.sendPresence(from, PresenceType.AVAILABLE, presence.getPresenceShow(), presence.getStatus());
To further clarify, your app receives automatic presence notifications via the following POST URL paths:
POSTs to /_ah/xmpp/presence/available/ signal that the user is available and provide the user's chat status.
POSTs to /_ah/xmpp/presence/unavailable/ signal that the user is unavailable.
POSTs to /_ah/xmpp/presence/probe/ request a user's current presence.
As an example, when user sally logs in, you'll get a POST request to /_ah/xmpp/presence/available/ which your server will then have to process. Then when sally logs out, you'll get a separate POST request to /_ah/xmpp/presence/unavailable/.