I'm building an PHP website. I want to push notification to client(who login to my website) so I use Firebase Cloud Messaging.
I already registered Firebase app and write a function to send message
public function sendMessage($data, $target)
{
//FCM api URL
$url = 'https://fcm.googleapis.com/fcm/send';
//api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
$server_key = 'MY SERVER KEY';
$fields = array();
$fields['data'] = $data;
if (is_array($target)) {
$fields['registration_ids'] = $target;
} else {
$fields['to'] = $target;
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key=' . $server_key
);
$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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
But I don't know how to get $target to let Firebase send message to.
Now I want when user register/login on my website, I will request token from Firebase and save it to my DB.
Because when I want send message to that user, I need provide target(token) for Firebase. Anyone please help me?
At first, client should have application that uses your firebase project.
Then you can sand message to it application, and you have 2 ways to do it:
You have to acquire his registration token
His app on smartphone should be registered in some topic, ex. "general".
Related
I want to push notification to my Ionic 2 app using firebase. I can push notification directly using firebase console, but I want to send it via php file.
when I send I get a response from PHP as: {"message_id":5718309985299480645}
And there is no notification in the phone.
I have placed this.fcm.subscribeToTopic('all') in the app.component.ts constructor.
I dont know what I am doing wrong..
this.fcm.subscribeToTopic('all') is the only code related to fcm in my app.
MY PHP CODE:
<?php
$data = array('title'=>'FCM Push Notifications');
$target = '/topics/mytopic';
//FCM API end-point
$url = 'https://fcm.googleapis.com/fcm/send';
//api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
$server_key = 'my_server_key_from_firebase';
$fields = array();
$fields['data'] = $data;
if(is_array($target)){
$fields['registration_ids'] = $target;
}else{
$fields['to'] = $target;
}
//header with content_type api key
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$server_key
);
//CURL request to route notification to FCM connection server (provided by Google)
$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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Oops! FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
echo $result;
?>
I EVEN TRIED PUSHBOTS BUT COULD NOT GET NOTFICATIONS ON THE DEVICE WITH PHP
I solved the problem by looking at fcm docs.
I changed the PHP file to:
$data = array('title'=>'Title of the notification', 'body'=>$msg, 'sound'=>'default');
$target = '/topics/notetoall';
$url = 'https://fcm.googleapis.com/fcm/send';
$server_key = 'my_server_api_key_from_firebase';
$fields = array();
$fields['notification'] = $data; // <-- this is what I changed from $fields['body']
if(is_array($target)){
$fields['registration_ids'] = $target;
}else{
$fields['to'] = $target;
}
All plugins must be called after the device ready, specially if they're beeing used in app.components (in some pages, that are not the first one, it can be used inside constructor since the app is already ready and plugins are loaded).
So subscribe to a topic on device ready
this.platform.ready().then(() => {
this.fcm.subscribeToTopic('all')
});
Hope this helps.
I'm going to send Firebase Cloud Messaging and the problem that I'm facing is I get an Unauthorized Error 401.
I got the security key from my Firebase website then set it. The device token is already in database and I read from database with no problem.
This is my code so far:
<?php
function send_notification($tokens, $message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array('registration_ids' => $tokens, 'data' => $message);
$headers = array('Authorization: key=' . "My Firebase key", 'Content-Type: application/json');
echo "work well before init curl";
$ch = curl_init();
echo "init well";
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_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
echo "init finishe well";
$result = curl_exec($ch);
echo "Execute to get result";
if ($result === false) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
echo "function finished well";
return $result;
}
$conn = mysqli_connect("localhost", "root", "mysql_password", "FCM") or die("Error connecting");
$sql = " Select Token From users";
$result = mysqli_query($conn, $sql);
$tokens = array();
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$tokens[] = $row["Token"];
}
}
mysqli_close($conn);
$message = array("message" => " FCM PUSH NOTIFICATION TEST MESSAGE");
$message_status = send_notification($tokens, $message);
echo $message_status;
?>
When using FCM, you must use the Server Key seen in the Cloud Messaging tab of your Firebase Console as the value for Authorization in your requests.
Using the documentation at https://developers.google.com/instance-id/reference/server, I wanted to use https://iid.googleapis.com/iid/info/IID_TOKEN to get information about app instances.
In the code of my app, I used this to get the IDD_TOKEN:
// Get token using example from https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/java/MainActivity.java.
// [START retrieve_current_token]
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
System.out.println("task.getResult().getToken() = "+token);
// Log and toast
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(FirstActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
// [END retrieve_current_token]
Then in the Android Studio logs, I found the token (I am changing the value of the token because I do not want to post the real one here):
I/System.out: task.getResult().getToken() = bepGr4F2b0Q:APB91cEAKsN1bGjMm5xsobxBHxuYZLfioTPMEIN90njdiK5C2MnOYF5NcOy6ot6XFanMTBIoKRGcyev5RJuydGWt1XHwsniNZ6h3Pjvn9Fqth-Mqgj_2-YN9pv_nMAugG8blc5boeDyH
This means that the IDD_TOKEN was bepGr4F2b0Q:APB91cEAKsN1bGjMm5xsobxBHxuYZLfioTPMEIN90njdiK5C2MnOYF5NcOy6ot6XFanMTBIoKRGcyev5RJuydGWt1XHwsniNZ6h3Pjvn9Fqth-Mqgj_2-YN9pv_nMAugG8blc5boeDyH. So in my PHP code I used this:
$curlUrl = "https://iid.googleapis.com/iid/info/bepGr4F2b0Q:APB91cEAKsN1bGjMm5xsobxBHxuYZLfioTPMEIN90njdiK5C2MnOYF5NcOy6ot6XFanMTBIoKRGcyev5RJuydGWt1XHwsniNZ6h3Pjvn9Fqth-Mqgj_2-YN9pv_nMAugG8blc5boeDyH?details=true";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $curlUrl);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
//turning off the server and peer verification(TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization:key=[My server key]'));
//getting response from server
$response = curl_exec($ch);
print_r($response);
Where is the [My server key] found? You can find it at https://console.firebase.google.com/. Go to the Cloud Messaging tab, and in the Project credentials section, you will find the Server key:
The result was this:
{"applicationVersion":"50","connectDate":"2019-05-09","attestStatus":"NOT_ROOTED","application":"[My package name]","scope":"*","authorizedEntity":"[My Firebase Sender ID]","rel":{"topics":{"Toronto":{"addDate":"2019-05-09"}}},"appSigner":"[My appSigner]","platform":"ANDROID"}
That is correct. I can tell that those values correspond to my IID_TOKEN for the device that I connected, I can recognize that and everything is correct. I can confirm that I subscribed my device to that topic and everything works correctly! I was able to use https://iid.googleapis.com/iid/info/IID_TOKEN to get information about my app instances corresponding to an Android device that I connected using Firebase.
After all passages for receive the notification with google cloud messaging in IOS but i have this problem:
i send the post in php for the notification with server key and device's token, at first time the response is "success" but not receive nothing on device, at the second time, and subsequent times, the response is "notRegistered". I repeat all passages: create new key in keychain, load in provisioning profile, download the .cer, install in keychain, export .p12 and insert the certificates on google platform for "GoogleService-Info.plist" and reload the device's regId at php, but the response is always this. Help me please.
This is my php :
$apiKey = "server key";
$regId = 'registration token';
$url = 'https://gcm-http.googleapis.com/gcm/send';
$post = '{"to" : "' . $regId . '", "content_available" : true, "priority" : "high", "notification": {"title" : "test", "body" : "test"}}';
$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, $post);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
if ( curl_errno( $ch ) )
{
echo 'GCM error: ' . curl_error( $ch );
}
curl_close( $ch );
echo $result;
Op's own answer, removed from the edited question:
The problem was the old account without the new provisioning profile, go to : XCode Accounts -> Apple IDs and view details -> Download All. For be sure go to : Targets -> project name -> Build Settings -> search "Provisioning Profile" -> change automatic and select your provisioning profile in use for certificates. The mystery is the xcode's reason don't warning me don't find the correct Provisioning Profile (different bundle id).
My five cents
In case you are having "notRegistered" error only when app is in production that was my mistake: I missed the that in the registration options provided in GCM:
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID
scope:kGGLInstanceIDScopeGCM
options:_registrationOptions
handler:self.registrationHandler];
There is an option kGGLInstanceIDAPNSServerTypeSandboxOption which should be set to NO in case of production
Hope it helps!
Some week ago, we also got NotRegistered error on second message send attempt. But For my experience, problem is not on ios side. The problem is on sent message parameters.
Please try to send all required and optional parameters.
Maybe you want to give a try to PHP script on this Q&A
Tip: Sending parameter "content_available as true, priority as high and notification as data" may help.
Below Example Json received with success again and again by ios devices.
"Content-Type" is "application/json"
{
"registration_ids":[
"<reg_id1>",
"<reg_id2>",
],
"priority":"high",
"content_available":true,
"time_to_live":2419200,
"data":{
"message":"Test 15:46:49",
"title":""
},
"notification":{
"title":"",
"body":"Test 15:46:49",
"sound":"default",
"badge":"1"
}
}
Edit 2:
Give a try that;
$apiKey = "server key";
$regId = 'registration token';
$url = 'https://gcm-http.googleapis.com/gcm/send';
$post = '{"to" : "' . $regId . '","priority":"high","content_available":true,"time_to_live":2419200,"data":{"message":"GCM Notifier:Message Success","title":"GCM Notifier:Title Success"},"notification":{"title":"GCM Notifier:Title Success","body":"GCM Notifier:Message Success","sound":"default","badge":"1"}}';
$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, $post);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
if ( curl_errno( $ch ) )
{
echo 'GCM error: ' . curl_error( $ch );
}
curl_close( $ch );
echo $result;
I am trying to get notification in my app using GCM. i am using android studio tool and i tried lots of tutorials. most of them where done using eclips tool.
finally, i tried this one,
http://rmarcejaeger.com/2015/09/18/tutorial-how-to-implement-push-notifications-using-google-cloud-messaging-for-android-part-1-client-app/#comment-576070,
https://github.com/googlesamples/google-services/tree/master/android/gcm
and i finish android client part using above tutorial. But the problem is, i need to setup app server in php which connect my application through GCM. i have no idea to make it possible. i tried the follwing link,
https://developers.google.com/cloud-messaging/server
but i couldn't get much more.So please anyone suggest me better solution.
you need to understand below steps
for more details Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL
First you need to create browser key from Console.
This is the code you need to add for Sending notification GOOGLE_API_KEY is the key you created from Console.
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
Now using this method of GCM class you can send notification to the device by calling its method.
pass reg.id that is token id you got from Android device and message you want to pass.
$gcm = new GCM();
$result = $gcm->send_notification($registatoin_ids, $message);
echo $result;
I am using the new Google Cloud messaging functionality and it's developed successfully in client side and receiving push notification without any dropping. But I'm using an old Send function on the server. Now I want to implement new send function (XMPP) using PHP.
I have registered here also https://services.google.com/fb/forms/gcm/ and got the response mail and key from the google.
And from that I got that I have to implement the SmackCcsClient Java class and two libraries. But I have no idea how to host that file to my PHP server.
After some research I got the function for PHP and xmphp libraries for PHP
$conn = new XMPPHP_XMPP($host, $port, $user, $password, $resource,
$server, $printlog, $loglevel);
But can't get the success it's saying could not connect.
You can use this class:
class gcm {
public static function send_notification($deviceid, $message) {
// include config
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => (is_array($deviceid) ? $deviceid : array($deviceid)),
'data' => array("message" =>$message),
);
$headers = array(
'Authorization: key=YOUR-AUTH-KEY',
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
}
}