Android: Push Notifcation toward an specified application package - php

I'm trying to setup a server to send push notifications.
I'm trying to send push notification toward user of an specified package e.g. something like com.mysite.android (This options is available in Firebase console).
Checking answers like this I could not understand how to set to parameter to send push notifications to user of an specified package. I can find sample which send notification to specific devices by their ids or news topics.
Clarification: I'm the owner of application which I want sent push notifications.
If it helps here is my code:
<?php
/*
Parameter Example
$data = array('post_id'=>'12345','post_title'=>'A Blog post');
$target = 'single tocken id or topic name';
or
$target = array('token1','token2','...'); // up to 1000 in one request
*/
echo "Start<br/>";
$result = sendMessage('{"id":"hello"}',null);
var_dump($result);
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 = 'xxxxxxxxxxxxxxxxxxxkeyxxxxxxxxxxxxxxxxxxxxxxxx';
$fields = array();
$fields['data'] = $data;
$fields['restricted_package_name']='com.mysite.android ';
$fields['dry_run']=true;
if (isset($target)){
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;
}
?>
Notice: I removed my server_key intentionally.

You cannot send push notifications to any external app except the apps you own, simply the user device token and your server key are linked under one project so you must use a server key and valid device tokens for "X" app

This is manageable. However, for you to be able to send a Notification to an app, you first need to be a valid Sender.
By that, usually (if you are the app owner), all you have to do is Add the App to your Firebase Project, generate the google-services.json file and add it to your Android Project.
If you're not the app owner and you don't want to add the app via your Firebase Project, this can be overridden by simply modifying the google-services.json that is used in the app, adding your SenderID in it. But I highly doubt that you'd be given access to modify an app that isn't yours in the first place.
Note: It is not advisable to modify your google-services.json though.
If you were able to set your peoject as a valid sender, you will have to make use of Topic Messaging and subscribe the devices to a topic name that is their app package name.
Then when sending to the topic, simply use the name of the package in the to parameter like so:
"to": "/topics/<app_package_name_here>"

Related

Send Push notification with Flutter + OneSignal for PlayerID

I'm creating a push, calendar-style push system. I need when I create a schedule for the user the system send a notification only to him, I created the system to manage this PHP, does anyone know how to help me?
If you're using OneSignal. You can send to that individual device with Playerid, you do however have to store the playerid serverside so that you know which device to send to. I personally do that in init state and do a http.post to my api to save the playerid into my database for that particular user.
You can of course achieve the same by using OneSignal's tags (useful if same person has multiple accounts in one device).
To send notification, use curl in php.
<?php
function sendMessage(){
$content = array(
"en" => 'English Message'
);
$fields = array(
'app_id' => "your-app-id",
'include_player_ids' => array("playerid-you-want-to-send-to"),
'data' => array("foo" => "bar"),
'contents' => $content
);
$fields = json_encode($fields);
print("\nJSON sent:\n");
print($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://onesignal.com/api/v1/notifications");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
$response = sendMessage();
$return["allresponses"] = $response;
$return = json_encode( $return);
print("\n\nJSON received:\n");
print($return);
print("\n");
?>
In Flutter, get the package, import it and:
void oneSignal() {
OneSignal.shared.init("app-id");
OneSignal.shared.setNotificationReceivedHandler((OSNotification notification)
{
//do what you need to do with upcoming notification, get title for example
print(notification.payload.title);
}
}
I'm far from an expert on mobile apps, so somebody should correct / confirm this.
To accomplish push notification in your app you could use a 'live' connection (websocket for instance) or you could use polling.
I don't know much about websockets and I don't think that's possible with CakePHP (not sure). EDIT: Definitely not possible out-of-the-box, but plugins exist.
When you are using polling you repeat a GET request every so often (once per hour, once per minute, depending on needs) and check if there is new info.
For instance, your CakePHP page could be an action taking a lastUpdated argument, which returns new information since that timestamp. The app then requests this page every x minutes, each time setting the lastUpdated parameter. When there is new info, the response will be not empty and the app can process it.
This does mean the app needs to always run in the background and the number of requests can become sizeable (depending on the polling interval).

Firebase MismatchSenderID when Authorization key is my Server key

Really weird and no one has ever asked this.
I'm getting MismatchSenderIdas an error with my server key as my authorization key(server key).
And on the other hand, I'm getting success as a return result from my push_notification() if my device's token as my authorization key, but no notification is received on my device.
I'm sure that my token is correct because I'm able to send to a single device with token in firebase (single device) console.
Which then leads me to this another question, but then I would like to confirm this issue before moving to the notification part
I'm pretty lost actually, since that all MismatchSenderId errors were resolved with replacing with the correct server key.
<?php
require "dbconfig.php";
$sql = "SELECT token FROM tokendb";
$result = mysql_query($sql) or die($sql."<br/><br/>".mysql_error());
$tokens = array();
while($row = mysql_fetch_assoc($result))
{
echo $row['token']; //this shows the same token compared to the token show in logcat(visual studio)
$tokens[] = $row["token"];
echo '<form id="form1" name="form1" method="post" action="">'.
'<p>From<br>'.
'<input type="text" size="100" maxlength="100" name="From" id="From" /><br>'.
'<p>Title<br>'.
'<input type="text" size="100" maxlength="100" name="Title" id="Title" />'.
'<br>'.
'<input type="submit" name="Send" id="Send" value="Send" />'.
'</form>';
}
$message = array("message" => "notification test");
$message_status = sendFCMMessage($message, $tokens);
echo $message_status;
function sendFCMMessage($message,$target){
//FCM API end-point
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array();
$fields['body'] = $message;
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=********'
);
//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);
return $result;
}
?>
EDIT: This short php code is also giving me MismatchSenderId error
<?php
$ch = curl_init("https://fcm.googleapis.com/fcm/send");
$header=array('Content-Type: application/json',
"Authorization: key=***(serverkey from project)");
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{ \"notification\": { \"title\": \"Test desde curl\", \"text\": \"Otra prueba\" }, \"to\" : \"my device's token\"}");
curl_exec($ch);
curl_close($ch);
?>
UPDATE
Uninstalling and reinstalling the app resolved the issue.
The MismatchSenderId error is encountered when you are attempting to send to a registration token that is associated with a different Sender (Project). From the docs:
A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration tokens won't work.
Make sure that the Server Key you are using is from the same Sender Project that the registration token is associated to. You can do this by checking your google-services.json file and see if the Sender ID there matches the Sender ID visible in the Firebase Project you are using to send the message.
For the matter of not receiving messages, It's a bit unclear as to what is the structure of payload that your code is sending. Try checking if it is a properly structured message payload with a notification and/or data message payload.
Make your you are taking Server Key from Right place
Now it is little bit tricky to get Server key for Notification from firebase.
Here are the Steps :
GO TO CONSOLE -> YOUR PROJECT -> PROJECT SETTINGS -> CLOUD MESSAGING (Second Tab)
And Take your Server Key and Sender id from their, which will work for you.
Uninstall the App and Re install it and try it.

App-to-Phone call Nexmo

I am new to Nexmo and I am trying to set up an App-to-Phone call. A voice call is initiated by the user of a mobile Ionic/Cordova app via the internet and a phone rings on the PSTN. The callee answers and both parties can speak and listen.
Now I have set up the server and I am able to get the phone on the PSTN to be called, I can answer it and I can use NCCO to speak a text to the callee.
I can't however, figure out how to handle Nexmo on the callers client side. How do I set up the connection between the app and the PSTN? How is the voice exchange sent and received via Nexmo? I can only find examples which use Text-to-Speech in the docs and the npm nexmo package.
My server has this code from the Nexmo docs:
<?php
include 'application_generate_jwt.php';
//Connection information
$base_url = 'https://api.nexmo.com' ;
$version = '/v1';
$action = '/calls';
//User and application information
$application_id = "id-for-your-voice-application";
//Mint your JWT
$keyfile="application_secret_key.txt";
$jwt = generate_jwt($application_id, $keyfile);
//Add the JWT to the request headers
$headers = array('Content-Type: application/json', "Authorization: Bearer " . $jwt ) ;
//Change the to parameter to the number you want to call
$payload = '{
"to":[{
"type": "phone",
"number": "441632960961"
}],
"from": {
"type": "phone",
"number": "441632960960"
},
"answer_url": ["https://nexmo-community.github.io/ncco-examples/first_call_talk.json"]
}';
//Create the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url . $version . $action);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
echo $response;
If more information is needed, please let me know!
There are 2 ways you can do this with Nexmo, it really depends if you know the phone number of the device with the app on it.
If so then you can make an outbound call to each phone number from nexmo and put them both into a simple conference (known as a conversation in NCCO speak)
https://docs.nexmo.com/voice/voice-api/ncco-reference#conversation
You just need to ensure that the name of the conversation is unique to that call.
The other way to do it would be via proxy calling so the app launches a 'tel:' url which contains a nexmo phone number which the client calls into and that then executes an NCCO that connects the call on to the destination number.
It depends on what your use case is as to which model would work best, also in option 1 you will bear the cost of 2 calls (one to each phone) in option 2 you will have one call cost and the user of the app with have the other.

how to implement push notification using GCM in android studio using php?

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;

Android Push Notification unauthorized error 401

I have created an Android app with Googles' OAuth 2.0 (from developer console) and has an API key for Android application (it use Google Maps, which works by the way).
However, my problem is that I'm using Push Notifications and it works on the android application though (I get the registration ID), but on the server it doesn't work at all.
I'm using PHP and the problem seems to be the API key which is the same as the one I've for the Android application.
So what key am I supposed to use? And how do I retrieve it?
Code:
<?php
function send_push_notification($registatoin_ids, $message) {
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=An_Api_Key',
'Content-Type: application/json'
);
//print_r($headers);
// 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;
}?>
Please check allowed IP addresses in your Google API. You can restrict API access to certain IP addresses and by default one IP address is set when you create new API project.
Remove that IP address so that any IP address (Including your local machine's server) can connect and access the API.
I have implemented similar kind of code and got 401 error. Above fix worked for me. Hope that helps you as well.

Categories