in the android app when having active notifications it can use
NotificationManager.getActiveNotifications()
to get the active notifications.
If the app configured with multiple notification groups and channels, how to find out what channel the active notification is belong to?
StatusBarNotification[] list = notificationManager.getActiveNotifications();
for(int i=0;i<list.length;i++) {
StatusBarNotification activeNoti = list[i];
Notification noti = activeNoti.getNotification();
//to get channel ID
String channelId = noti.getChannelId();
}
Note: notificationManager.getActiveNotifications() will only give the notification build by your app (it will not return the other notification which is not build by your app)
Related
I have successfully implemented a basic notification feature using react-native-firebase library, everything is working as expected, information is properly received and ready to be used for a purpose I have yet to determine. My code currently look like this for the notification handling part:
componentDidMount() {
/**
* When app on foreground, rewrap received notification and re-send it as notification using channelId
* A workaround because channelId never set by default by FCM API so we need to rewrap to make sure it is
* shown on user's notification tray
*/
this.notificationListener = firebase.notifications().onNotification((notification) => {
//data object must have channelId props as a workaround for foreground notification on Android
console.log('Notif ', notification);
notification.android.setChannelId(notification.data.channelId);
firebase.notifications().displayNotification(notification);
});
//On Notification tapped, be it from foreground or background
this.notificationOpen = firebase.notifications().onNotificationOpened((notificationOpen) => {
//body and title lost if accessed from background, taking info from data object by default
const notification = notificationOpen.notification;
console.log('Open ', notification)
Alert.alert(notification.data.title, notification.data.body);
});
//When notification received when app is closed
this.initialNotification = firebase.notifications().getInitialNotification()
.then((notificationOpen) => {
//body and title lost if accessed this way, taking info from data object where info will persist
if (notificationOpen) {
const notification = notificationOpen.notification;
console.log('Initial ', notification)
Alert.alert(notification.data.title, notification.data.body);
}
});
}
componentWillUnmount() {
this.notificationListener();
this.initialNotification()
this.notificationOpen();
}
The above code let me use any information I sent from firebase console or a php server set up by my colleague from within the above scope (not sure how the server side implementation was done, but it gives me the exact same notification object on my end).
So that's good and all, but the problem is when I set badge on IOS from firebase console, the badge doesn't go away once I opened the notification.
I have been trying to figure out if there's any extra bit I have to add to the above block to programatically decrement the badge counter, but have no luck so far.
So if anyone here can show me how to manage these notification objects properly (especially explaining the nature and lifecycle of these objects -- i.e. which data on which property/method persists or is static within the scope of the notification object) on both Android and IOS, that would be greatly appreciated :)
Turns out a simple firebase.notifications().setBadge(0) on root componentDidMount() clears out the badge count whenever the app is opened.
May need to use firebase.notifications().removeAllDeliveredNotifications() or firebase.notifications().cancelAllNotifications() to remove them from notification tray too.
May be you have to set code for badge while creating a notification
this.notificationListener = firebase.notifications().onNotification((notification) => {
const localNotification = new firebase.notifications.Notification()
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setSubtitle(notification.subtitle)
.setBody(notification.body)
.setData(notification.data)
.ios.setBadge(notification.ios.badge);
firebase.notifications()
.displayNotification(localNotification)
.catch(err => console.error(err));
}
Put this line in code .ios.setBadge(notification.ios.badge); while building a notification and try again
Currently developing a Cordova app and wanted to use the IBM Bluemix Push Notification service to send user based push notifications.
According to the documentation here, seems like the first step is to call MFPPush.initialize(appGuid, clientSecret), which I tried to do. But this function is not present in the plugin interface and therefore I get an 'undefined' error when running the app.
Moreover, the doc also talks about calling MFPPush.registerDevice({},success,failure,userId). However, when I look at the plugin javascript interface, it only takes 3 parameters.
Could someone please give some advice to help me sort this out?
Thanks.
I just ran the Bluemix Cordova hellopush sample which should help you out. Make sure you follow the directions in the README, and make sure to change the route and guid in your index.js (it should look something like this):
route: "http://imfpush.ng.bluemix.net",
guid: "djkslk3j2-4974-4324-8e82-421c02ce847c",
You will be able to find the route and guid in your Push Notifications service credentials.
After running it by following the directions (and ensuring that you have GCM / APNS set up correctly for whatever platform you are using), you should be greeted with this screen after clicking register:
#johan #joe Cordova app can use the IBM Bluemix Push Notification service to send user based push notifications. Please follow the below example using BMSPush to register for Push Notifications.
// initialize BMSCore SDK
BMSClient.initialize("Your Push service region");
// initialize BMSPush SDK
var appGUID = "Your Push service appGUID";
var clientSecret = "Your Push service clientSecret";
// Initialize for normal push notifications
var options = {}
BMSPush.initialize(appGUID,clientSecret,options);
// Initialize for iOS actionable push notifications and custom deviceId
var options ={"categories":{
"Category_Name1":[
{
"IdentifierName":"IdentifierName_1",
"actionName":"actionName_1",
"IconName":"IconName_1"
},
{
"IdentifierName":"IdentifierName_2",
"actionName":"actionName_2",
"IconName":"IconName_2"
}
]},
"deviceId":"mydeviceId"
};
BMSPush.initialize(appGUID, clientSecret, options);
var success = function(response) { console.log("Success: " + response); };
var failure = function(response) { console.log("Error: " + response); };
// Register device for push notification without UserId
BMSPush.registerDevice(options, success, failure);
// Register device for push notification with UserId
var options = {"userId": "Your User Id value"};
BMSPush.registerDevice(options, success, failure);
Please go through the Bluemix Cordova Plugin Push SDK doc link.
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
We have a pretty big issue in our app which is set up to receive GCM push notifications: Without launching a push notification, the app receives a push notification - this happens every day!
I've implemented a GCM Client (and obviously the Server side too) pretty much exactly as stipulated here: http://developer.android.com/google/gcm/client.html and here http://developer.android.com/google/gcm/client.html#sample-receive
Here is my onHandleIntent function in my GCMIntentService:
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
// If it's a regular GCM message (and the user is logged in), do some work.
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType) && prefsMan.getLoggedIn(this)) {
// Post notification of received message.
sendNotification(extras.getString("message"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
What is causing the push notification from appearing every day, without it being launched from the server side?
Just as a side note, if I could set a bounty on this today already, I would do it, so please - any help will be appreciated, and I'll eventually give some of my rep to anyone who can help me with this issue, as soon as I'm allowed to do this on SO (two days from now).
We are trying to run the sample app for push notifications with some modification to get it to send out a broadcast notification, but it is not getting sent.
We have modified the PushBackendEmulator code as well. The emulator invokes the submitBroadCastNotification procedure successfully and the following result is returned:
Server response :: /-secure-{"result":"Notification sent to all
users","isSuccessful":true}/
However, it appears the WL.Server.sendMessage method is not sending the message and returns. I am not able to see the server side logs either after a thorough search on the liberty server except for the messages.log on the liberty server which shows the following when WL.Server.sendMessage is called.
ht.integration.js.JavaScriptIntegrationLibraryImplementation E
FWLSE0227E: Failed to send notification. Reason: FPWSE0009E: Internal
server error. No devices found [project worklight]
Here is the adapter code:
function submitBroadcastNotification( notificationText) {
var notification = {};
notification.message = {};
notification.message.alert = notificationText;
//notification.target = {};
//notification.target.tagNames = ['test'];
WL.Logger.debug("broadcast: " + notification.message.alert );
var delayTimeOut = **WL.Server.sendMessage**("PushNotificationsApp", notification);
WL.Logger.debug("Return value from WL.Server.sendMessage :"+ delayTimeOut);
return {
result : "Notification sent to all users"
};
}
Here is the PushBackendEmulator code:
public static void main(String [] args){
String serverUrl =
"http://208.124.245.78:9080/worklight";
String notificationText = "Hellofrombroadcastingnotifications";
String userId = "admin";
notificationText = notificationText.replace(" ", "%20");
Logger.debug("sending broadcast notification: " + notificationText);
URL url = new URL(serverUrl
+ "/invoke?
adapter=PushAdapter&procedure=submitBroadcastNotification¶meters=['" + userId + "','" + notificationText + "']");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(10000);
connection.setDoOutput(true);
Logger.debug("Connected to server");
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = "";
String inputLine;
while ((inputLine = in.readLine()) != null)
response+= inputLine;
Logger.debug("response is:"+ response);
in.close();
Logger.debug("Server response :: " + response);
connection.disconnect();
Looking at your application from the PMR, it seems to me like you have mixed both event source-based notifications and broadcast notifications.
If you want to use Broadcast notifications, this means you cannot try imposing sending the notification to any specific userId, etc as it is not needed nor based on userIds.
By default, all devices are auto-subscribed to a tag called "push.ALL".
You can read more about broadcast notifications API methods in the IBM Worklight Knowledge Center.
This is a modified version of your application, tested in iOS and Android: https://www.dropbox.com/s/l2yk2pbvykrzfoh/broadcastNotificationsTest.zip?dl=0
Basically, I stripped away from it anything not related to broadcast notifications:
I removed the push securitytest from application-descriptor.xml
I removed any function from the adapter XML and JS files and main.js file that is related to event source-based notifications.
The end result is that after the app is loaded, you are right inside the application (no login).
I then right-clicked the adapter folder in Studio > invoke procedure, and selected the submitBroadcastNotification option to send the notification ("aaa").
In the device, a notification was received. Tapping it (if the app is closed) launches the application, which then triggers the WL.Client.Push.onMessage API in common\js\main.js to display alerts containing the payload and props of the received notification.
This was tested in both iOS and Android.
As the application was loading, I could see in LogCat and Xcode console the token registration.
To test this in iOS, you will need to update application-descriptor.xml with your own pushSender password and add your own apns-certificatae-sandbox.p12 file.
To test in Android, make sure you are have generated a browser key in the GCM console and are using it in application-descriptor.xml
For both, make sure that all requires ports and addresses and accessible in your network