I am trying to push a notification from a plugin using firebase so that the notification is received by the android app.
I have the API key from google but don’t know how to get the device token so that I can push notification using CURL.
This is a post from Sending Firebase notification with PHP I have been following but stuck in device token. How can I get it?
This what the link mentioned above has recommended:
<?php
$message = 'ojlaasdasdasd';
$title = 'ojla';
$path_to_fcm = 'https://fcm.googleapis.com/fcm/send'; $server_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx5LnDZO2BpC2aoPMshfKwRbJAJfZL8C33qRxxxxxxxxxxxxL6';
$key = 'eqnlxIQ1SWA:APA91bGf1COAZamVzT4onl66_lEdE1nWfY7rIADcnt9gtNYnw7iWTwa7AYPYTHESFholkZ89ydCQS3QeL-lCIuiWTXiqoDREO0xhNdEYboPvqg8QsBYkrQVRlrCLewC4N-hHUja1NG4f';
$headers = array(
'Authorization:key=' .$server_key,
'Content-Type: application/json');
$fields = array
(
'to' => $key,
'notification' => array('title' => $title,'body' => $message)
);
$payload = json_encode($fields);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, '$path_to_fcm' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt( $ch,CURLOPT_POSTFIELDS, $payload);
$result = curl_exec($ch);
echo $result;
curl_close($ch);
?>
Any help on this would be highly appreciated.
The easiest way is to enable subscription to a topic by the device. The below code will subscribe the users to the topic named "ALL-USERS".
Now while sending messages using CURL, use the 'to' field as '/topics/ALL-USERS'!
FirebaseMessaging.getInstance().subscribeToTopic("ALL-USERS").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
sharedPref.setSubscibeNotif(task.isSuccessful());
}});
Related
I am sending push notification from laravel which I am using as a backend for my app.
I am not getting the push notification on android Oreo, but on lower versions, I am getting it.
What changes should I have to do for getting the notification in android oreo?
Here is the code of fcm.php
<?php
class Fcm {
//Define SendNotification function
function sendNotification($dataArr) {
$fcmApiKey = 'SERVER_KEY';//App API Key(This is google cloud messaging api key not web api key)
$url = 'https://fcm.googleapis.com/fcm/send';//Google URL
$registrationIds = $dataArr['device_id'];//Fcm Device ids array
$message = $dataArr['message'];//Message which you want to send
$title = $dataArr['title'];
$image=$dataArr['image'];
$news_id=$dataArr['news_id'];
$random=$dataArr['random_id'];
// prepare the bundle
$msg = array('message' => $message,'title' => $title,"image"=>$image,"news_id"=>$news_id,"random_id"=>$random);
$fields = array('registration_ids' => $registrationIds,'data' => $msg);
$headers = array(
'Authorization: key=' . $fcmApiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, $url );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
$_SESSION['result']=$result;
return $result;
}
}
Here is the code of send.php
<html><head><script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script></head><body>
<?php
include 'config.php';
//echo '<pre>';
$title=$_POST['title'];
$msg=$_POST['msg'];
$news_id=$_POST['news'];
//echo $news_id;
//echo msg;
//echo $image;
$sql="SELECT image FROM `app_news` where id='".$news_id."' ";
$check= mysqli_query($con, $sql);
$resultcheck= mysqli_fetch_array($check,MYSQLI_ASSOC);
$random=rand(0,999);
$image=$resultcheck['image'];
$data=array("title"=>$title,"message"=>$msg,"image"=>$image,"news_id"=>$news_id,"random_id"=>$random,"priority" => 10);
///echo'<pre><h1> Data sent through request:<br>';var_dump($data); echo '</h1><br>';
////////////////////////////////GETTING DEVICE DATA///////////////////////////////////
$sql="SELECT * FROM `devices`";
$checkdevices= mysqli_query($con, $sql);
$DeviceIdsArr= array();
//Prepare device ids array
while($rowData = mysqli_fetch_array($checkdevices,MYSQLI_ASSOC)) {
$DeviceIdsArr[] = $rowData['token'];
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////SENDING NOTIFICATION//////////////////////////////////////////
require("fcm.php");
$fcm = new Fcm();//Create Fcm class object
$dataArr = array();
$dataArr['device_id'] = $DeviceIdsArr;//fcm device ids array which is created previously
$dataArr['message'] = $data['message'];//Message which you want to send
$dataArr['image'] = $data['image'];
$dataArr['title'] = $data['title'];
$dataArr['news_id'] = $data['news_id'];
$dataArr['random_id'] = $data['random_id'];
$dataArr[ 'priority'] = $data['priority'];
//Send Notification
$fcm->sendNotification($dataArr);
//var_dump($_SESSION['result']);//
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
$results[]=json_decode($_SESSION['result']);
///////////////showing results//////////////
$multicast_id=$results[0]->multicast_id;
$success=$results[0]->success;
$fail=$results[0]->failure;
$message_id=$results[0]->results[0]->message_id;
///////////////////////////////////////////////////
if($success!=''){?>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script type="text/javascript">
swal({
title: "Notification sent",
text: "successfully ",
icon: "success",button: "close"
}).then(function() {
//Redirect the user
window.location.href = "notification.php";
//console.log('The Ok Button was clicked.');
});
</script>
<?php } ?>
Please consider the following issue:
I am using the following plugin for Xamarin to perform push notifications, I am attempting to get this running on both iOS and Androids.
https://github.com/CrossGeeks/FirebasePushNotificationPlugin
I am also using the following PHP code to send push notifications to the device from a website.
$fields = array
(
'to' => $ID->notification_token,
"content_available" => true,
'priority'=>10,
'notification' => array('title' => 'You have a new message', 'body' => 'Hooray', 'sound'=>'default', 'vibration'=>'default'),
);
$headers = array
(
'Authorization: key=' . PUSH_NOTIFICATION_API_ACCESS_KEY,
'Content-Type: application/json',
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
Now the issue is on iOS I find that the push notification is reliable and runs perfectly when the app is in the foreground, but as soon as I background it (or lock the screen), they stop coming through until I foreground it again, then all of the notifications sent while it was in the background all come through at once.
I have enabled background processes in my info.plist as according to the plugins "Getting Started" guide.
I have tried changing content_availiable to content-availiable, also moving it into the notification array, also setting the value of it to true, 'true', 1 and '1'
I have also tried adding "alert" => "" to both the notification and the overall payload, however I still can't get it to work, outside of the foreground unlocked state.
I also notice that nothing appears to be triggering in the actual notification list (Pulled down from top of screen), the only way I know that the notifications are being received is from playing a certain sound file as it comes through and writing in the debug log.
Any assistance will be appreciated, thanks for your time.
Make sure your message Json has the {"content-available" : "1", "alert" : ""} attributes if you want it to show up on iOS when not running in background.
As for Android, push notifications really are not 100% realiable, there are device specific impediments that may block your notification from showing up.
There might be a "test send" feature on Firebase (I've only used Azure Push Hub so far) so you can try and see if your message Json is configured correctly.
I would try sending a Data Message instead
$fields = array
(
'to' => $ID->notification_token,
"content_available" => true,
'priority'=>10,
'data' => array('title' => 'You have a new message', 'body' => 'Hooray', 'sound'=>'default', 'vibration'=>'default'),
);
Use ApnsConfig to show alerts in iOS when the app is in background. This worked for me.
var pushMessage = new FcmMessage
{
Data = new Dictionary<string, string>
{
{ Constants.PushMessages.MessageId, $"{message.MessageId}" },
{ Constants.PushMessages.TopicId, $"{message.TopicId}" },
{ Constants.PushMessages.Type, $"{message.Type}" },
{ Constants.PushMessages.Title, message.Title },
{ Constants.PushMessages.Content, message.Content },
{ Constants.PushMessages.CreatedBy, message.CreatedBy },
{ Constants.PushMessages.CreatedOn, $"{message.CreatedOn}" }
},
Token = registrationToken,
Apns = new ApnsConfig
{
Aps = new Aps
{
Alert = new ApsAlert
{
Title = message.Title,
Body = message.Content
}
}
}
};
await FirebaseMessaging.DefaultInstance.SendAsync(pushMessage);
The response says the notification was successful, but it has not been displayed on my Android phone.
Response:
{"multicast_id":6696507350475373329,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1486651908616097%298b4204f9fd7ecd"}]}
PHP (src: https://gist.github.com/prime31/5675017)
<?php
// API access key from Google API's Console
define( 'API_ACCESS_KEY', ThisIsMyKey);
$registrationIds = array( $_GET['id'] );
// prep the bundle
$msg = array
(
'message' => 'TestNachricht',
'title' => 'TestTitel',
'subtitle' => 'TestSubTitle',
'vibrate' => 1,
'sound' => 1,
'priority' => 10,
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
Android:
I did not add onReceive-Methods because I am able to broadcast notifcations and send notifications to specific devices (RegistrationId) using FireBase Console. All of them are displayed on my device.
private String getRegistrationId() {
return FirebaseInstanceId.getInstance().getToken();
}
<service android:name=".MyFirebaseInstanceIdService" android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
When sending push notifications via the Firebase Console, it is classified as a notification message payload. By default, Android will handle this message when your app is in background.
In your PHP code, you're sending a data-only message payload, which can be handled in Android by implementing onMessageReceived().
If you still prefer not to implement onMessageReceived(), you'll have to modify your PHP side code to use a notification-only message payload.
Note that the notification payload only has predefined parameters that can be used.
More details here:
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
I just need to send push notifications to a handful of devices. I have their device tokens in an array. Do I need to create topics or groups for this?
I can send push notifications individually using a for loop, but is there a better way to do this?
EDIT: Please do not mark this question as duplicate without understanding. The question
FCM (Firebase Cloud Messaging) Send to multiple devices
has answers to use FCM Token and groups, which I have clearly stated that is not my requirement. As far as 'registration_ids' mentioned by other question is concerned its not mentioned anywhere in the official docs , if it is mentioned then please point it out as a valid answer.
Use "registration_ids" instead of "to".
var message = {
registration_ids:['id1','id2','id3'],
notification: {
title: 'Hello There...!',
body: 'this is test notification'
}
};
Hope It Works..!!!
I know this has been answered and not a very latest question.
Sure, you can construct the string array and send it like this as mentioned in the google documentation find here.
HTTP POST request
For example, to add a device with the registration ID 51 to appUser-Chris, you would send this request:
{
"operation": "add",
"notification_key_name": "appUser-Chris",
"notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
"registration_ids": ["51"] //you can insert something more of your strings here.
}
Response format
A successful request to either add or remove a device returns a notification_key like the following:
{
"notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}
<?php
// Your code here!
class FCM
{
private $key;
function __construct($api_key)
{
$this->key = $api_key;
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $notification)
{
$fields = array ( 'to' => $registatoin_ids,'notification' => $notification); //'restricted_package_name' => "com.apps.firebasenotificationphp");
$headers = array (
'Authorization: key=' . $this->key,
'Content-Type: application/json'
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, "https://fcm.googleapis.com/fcm/send" );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, json_encode($fields) );
return curl_exec ( $ch );
curl_close ( $ch );
}
}
$api_key = "";
$device_id = "";
$fcm = new FCM($api_key);
$arrNotification = array ("body" => "hii","title" => "hello",'image' => "https://www.gstatic.com/devrel-devsite/prod/vb1c70bbe2f68b543db3deb1075af42e62f8f21e5fc703b8398dc6b9860f1711f/firebase/images/lockup.png",'link' => "",'sound' => "default");
echo $fcm->send_notification($device_id,$arrNotification);
?>
I'm trying to send a non-collapse message via Google Cloud Messaging. For some reason a new message always replaces the previous one. I've tried to use different collapse-keys with no effect. Also omitting the collapse key does not work. What could be the problem?
This is an example code:
<?php
$ids[] = '<notification registration id of the test phone>';
sendNotification($ids, "test message 1", "key1");
sendNotification($ids, "test message 2", "key2");
function sendNotification($ids, $message, $collapseKey)
{
$apiKey = '<api key here>';
$url = 'https://android.googleapis.com/gcm/send';
$data['title'] = 'AppName';
$data['message'] = $message;
$post['registration_ids'] = $ids;
$post['data'] = $data;
if ($collapseKey) {
$post['collapse_key'] = $collapseKey;
}
$headers = array(
'Authorization: key=' . $apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $post ) );
$result = curl_exec( $ch );
if ( curl_errno( $ch ) )
{
echo 'GCM error: ' . curl_error( $ch );
}
curl_close( $ch );
echo $result;
}
?>
From the GCM collapse key documentation, omitting the collapse-key should prevent replacing the old messages. Unless some of your messages already expired or your devices are not connected.
Also, the NOTIFICATION_ID with notify method call is implemented in your client application, not your service side code. So it should not be mattered if you are using HTTP server. You can refer to this documentation about NOTIFICATION_ID in your client application's broadcast receiver. Also this StackOverflow answer about how to generate unique NOTIFICATION_ID.
I am going to answer my own question.
There are two scenarios:
For instance: you send two messages when your phone is offline (no wifi, no data, turned off)
Background/killed app -
I only get one notification, but actually i get the two data-message
Foreground -
I get the two notification
Please remember not to add "collapse_key" parameter.
Hope this can help anyone else with the same problem.