Reputation: 39
I'm getting a notification only in one device that is set as the first token stored the table in mySQL DB and the notification is not sent to the rest of the token numbers. I tried a WHILE
loop and stored the token numbers in an array, but it did not work.
Please suggest a solution. Thank you.
Here is my code:
<?php
require "init.php";
$message=$_POST['message'];
$title=$_POST['title'];
$path_to_fcm='https://fcm.googleapis.com/fcm/send';
$server_key="A*************************Q";
$sql="select token from fcm_info";
$result =mysqli_query($con,$sql);
$row=mysqli_fetch_row($result);
$key=$row[0];
$headers = array(
'Authorization:key=' .$server_key,
'Content-Type:application/json'
);
$fields =array('to'=>$key,
'notification'=>array('title'=>$title,'body'=>$message));
$payload =json_encode($fields);
$curl_session =curl_init();
curl_setopt($curl_session,CURLOPT_URL, $path_to_fcm);
curl_setopt($curl_session,CURLOPT_POST, true);
curl_setopt($curl_session,CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_session,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl_session,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_session,CURLOPT_IPRESOLVE, CURLOPT_IPRESOLVE);
curl_setopt($curl_session,CURLOPT_POSTFIELDS, $payload);
$result=curl_exec($curl_session);
curl_close($curl_session);
mysqli_close($con);
?>
Upvotes: 2
Views: 8672
Reputation: 1293
////////////////////// FCM START /////////////////////////
$path_to_fcm = "https://fcm.googleapis.com/fcm/send";
$server_key = "your_server_key";
$headers = array(
'Authorization:key=' . $server_key,
'Content-Type:application/json');
$keys = ["key_1", "key_2"];
$fields = array(
"registration_ids" => $keys,
"priority" => "normal",
'notification' => array(
'title' => "title of notification",
'body' => "your notification goes here"
)
);
$payload = json_encode($fields);
$curl_session = curl_init();
curl_setopt($curl_session, CURLOPT_URL, $path_to_fcm);
curl_setopt($curl_session, CURLOPT_POST, true);
curl_setopt($curl_session, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_session, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_session, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl_session, CURLOPT_POSTFIELDS, $payload);
$curl_result = curl_exec($curl_session);
////////////////////// FCM END /////////////////////////
This works for me.
Upvotes: 0
Reputation: 2203
"Please suggest a solution"
I would like to suggest using Services. You're most recommended to read the documention by Android Studio here.
There is a lot to perceive about Services, but at the moment I believe a snippet will be most helpful to you, here is a little code,
Create a class called HelloService
and paste the following code inside with the proper imports*
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "servicestarting",Toast.LENGTH_SHORT).show();
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
"This is overhwleming" you might think to yourself. However it's but the contrary.
Example for Services + Firebase
Instead of pushing a message from Firebase, let's say you want to notify a user whenever a modification takes place in one of your databases
first, create databasereference earlier on the Oncreate
mDatabaseLike=FirebaseDatabase.getInstance().getReference().child("Likes");
Go to 'handleMessage Method' and add the following
@Override
public void handleMessage(Message msg) {
mDatabaseLike.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
notifyUserOfDBupdate()
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
//stopSelf(msg.arg1);
}
}
Here is the notifyUserOfDBupdate method and how to notify a user
private void notifyUserOfDBupdate() {
//Intents
Intent Pdf_view = new Intent(this, //class to throw the user when they hit on notification\\.class);
PendingIntent pdf_view = PendingIntent.getActivity(this, 0, Pdf_view, 0);
//Notification Manager
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
//The note
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification noti = new NotificationCompat.Builder(getApplicationContext())
.setTicker("TickerTitle")
.setContentTitle("content title")
.setSound(soundUri)
.setContentText("content text")
.setContentIntent(pdf_view).getNotification();
//Execution
noti.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(0, noti);
}
Now run your application once on your real device and a second time on an emulator. Once either one of two modifies your firebase database, the other will be notified instantly.
Modify whichever method you like inside the HandleMessage method. It will be eternal, not unless you make it killable.
kindest regards
Upvotes: -1
Reputation: 2234
Use 'registration_ids' instead of 'to' and pass comma separated multiple registrations ids to use multicast in FCM. Final payload should be like:
{
"registration_ids":["id1","id2",...],
"priority" : "normal",
"data" : {
"title" : "Title",
"message" : "Message to be send",
"icon": "icon_path"
}
}
see https://developers.google.com/cloud-messaging/http-server-ref for more help
Upvotes: 6
Reputation: 348
You need to cover the notification sending logic in method and then start the loop & call that method in each iterations pass token and message to the method.
Upvotes: -1