如何使用 FCM 令牌在 Android 中向特定用户发送通知?

huangapple go评论81阅读模式
英文:

How do I send notification to a specific user in Android using FCM token?

问题

I'm asking how I can send a notification to a specific user device by using the FCM token. The token is stored in the RealtimeDatabase in Firebase which is structured like this:

project-name: {
   users: {
      username: {
         name: "..."
         token: "..."
      }
   }
}

This is the code I use to store the token:

FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
    @Override
    public void onComplete(@NonNull Task<InstanceIdResult> task) {
       if (task.isSuccessful()) {
          String token = task.getResult().getToken();
          saveToken(token);
       }
    }
});

private void saveToken(String token) {
   reference.setValue(token);
}

where "reference" is the correct pointer to the db.. this works properly.

I want to use the token stored to send a push-notification to the user targeted.

I also have implemented the class MyFirebaseMessagingService but I don't know how to use it to send notification to a specific user using his FCM token that I stored as I posted above.

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "From: " + remoteMessage.getFrom());

    }

    @Override
    public void onNewToken(String token) {
        Log.d(TAG, "Refreshed token: " + token);

        sendRegistrationToServer(token);
    }

    private void sendRegistrationToServer(String token) {
        //here I have code that store the token correctly
    }

    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_default)
                        .setContentTitle(getString(R.string.fcm_message))
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0, notificationBuilder.build());
    }
}

So I want to target a specific user by his FCM token and sending him a notification but I can't find a way to do this. Please help me.

英文:

I'm asking how I can send a notification to a specific user device by using the FCM token. The token is stored in the RealtimeDatabase in Firebase which is structured like this:

project-name: {
users: {
username: {
name: &quot;...&quot;
token: &quot;...&quot;
}
}
}

This is the code I use to store the token

    FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener&lt;InstanceIdResult&gt;() {
@Override
public void onComplete(@NonNull Task&lt;InstanceIdResult&gt; task) {
if (task.isSuccessful()) {
String token = task.getResult().getToken();
saveToken(token);
}
}
});
private void saveToken(String token) {
reference.setValue(token);
}

where "reference" is the correct pointer to the db.. this works properly.
I want to use the token stored to send a push-notification to the user targeted.
I also have implemented the class MyFirebaseMessagingService but I don't know how to use it to send notification to a specific user using his FCM token that I stored as I posted above.

public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, &quot;From: &quot; + remoteMessage.getFrom());
}
@Override
public void onNewToken(String token) {
Log.d(TAG, &quot;Refreshed token: &quot; + token);
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
//here I have code that store the token correctly
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_default)
.setContentTitle(getString(R.string.fcm_message))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
&quot;Channel human readable title&quot;,
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0, notificationBuilder.build());
}
}

So I want to target a specific user by his FCM token and sending him a notification but I can't find a way to do this. Please help me.

答案1

得分: 2

要向特定用户发送通知,您需要调用此API:

https://fcm.googleapis.com/fcm/send

使用授权:"key=YOUR_FCM_KEY" 和内容类型:"application/json" 作为标头,请求体应如下:

{ 
&quot;to&quot;: &quot;FCM Token&quot;,
&quot;priority&quot;: &quot;high&quot;,
&quot;notification&quot;: {
&quot;title&quot;: &quot;Your Title&quot;,
&quot;text&quot;: &quot;Your Text&quot;
},
&quot;data&quot;: {
&quot;customId&quot;: &quot;02&quot;,
&quot;badge&quot;: 1,
&quot;sound&quot;: &quot;&quot;,
&quot;alert&quot;: &quot;Alert&quot;
}
}

您应该从后端调用此API(推荐)。您也可以从Android设备调用它,但是要注意防止API密钥被劫持。

对于Android,您可以使用 okhttp 来调用API:

implementation("com.squareup.okhttp3:okhttp:4.9.0")

示例代码如下:

public static void senPushdNotification(final String body, final String title, final String fcmToken) {
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                OkHttpClient client = new OkHttpClient();
                JSONObject json = new JSONObject();
                JSONObject notificationJson = new JSONObject();
                JSONObject dataJson = new JSONObject();
                notificationJson.put("text", body);
                notificationJson.put("title", title);
                notificationJson.put("priority", "high");
                dataJson.put("customId", "02");
                dataJson.put("badge", 1);
                dataJson.put("alert", "Alert");
                json.put("notification", notificationJson);
                json.put("data", dataJson);
                json.put("to", fcmToken);
                RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
                Request request = new Request.Builder()
                        .header("Authorization", "key=YOUR_FCM_KEY")
                        .url("https://fcm.googleapis.com/fcm/send")
                        .post(requestBody)
                        .build();
                Response response = client.newCall(request).execute();
                String finalResponse = response.body().string();
                Log.i("TAG", finalResponse);
            } catch (Exception e) {
                Log.i("TAG", e.getMessage());
            }
            return null;
        }
    }.execute();
}
英文:

To send the notification to a specific user you have to call this API:

https://fcm.googleapis.com/fcm/send

with Authorization:"key=YOUR_FCM_KEY" and Content-Type:"application/json" in header and the request body should be like:

{ 
&quot;to&quot;: &quot;FCM Token&quot;,
&quot;priority&quot;: &quot;high&quot;,
&quot;notification&quot;: {
&quot;title&quot;: &quot;Your Title&quot;,
&quot;text&quot;: &quot;Your Text&quot;
},
&quot;data&quot;: {
&quot;customId&quot;: &quot;02&quot;,
&quot;badge&quot;: 1,
&quot;sound&quot;: &quot;&quot;,
&quot;alert&quot;: &quot;Alert&quot;
}
}

You should call this api from backend (Recommended). You can also call it from your android device,
but

> Be aware of hijacking your API Key

For android you can use okhttp for calling API

implementation(&quot;com.squareup.okhttp3:okhttp:4.9.0&quot;)

and the sample code will be like

public static void senPushdNotification(final String body, final String title, final String fcmToken) {
new AsyncTask&lt;Void, Void, Void&gt;() {
@Override
protected Void doInBackground(Void... params) {
try {
OkHttpClient client = new OkHttpClient();
JSONObject json = new JSONObject();
JSONObject notificationJson = new JSONObject();
JSONObject dataJson = new JSONObject();
notificationJson.put(&quot;text&quot;, body);
notificationJson.put(&quot;title&quot;, title);
notificationJson.put(&quot;priority&quot;, &quot;high&quot;);
dataJson.put(&quot;customId&quot;, &quot;02&quot;);
dataJson.put(&quot;badge&quot;, 1);
dataJson.put(&quot;alert&quot;, &quot;Alert&quot;);
json.put(&quot;notification&quot;, notificationJson);
json.put(&quot;data&quot;, dataJson);
json.put(&quot;to&quot;, fcmToken);
RequestBody body = RequestBody.create(MediaType.parse(&quot;application/json; charset=utf-8&quot;), json.toString());
Request request = new Request.Builder()
.header(&quot;Authorization&quot;, &quot;key=YOUR_FCM_KEY&quot;)
.url(&quot;https://fcm.googleapis.com/fcm/send&quot;)
.post(body)
.build();
Response response = client.newCall(request).execute();
String finalResponse = response.body().string();
Log.i(&quot;TAG&quot;, finalResponse);
} catch (Exception e) {
Log.i(&quot;TAG&quot;, e.getMessage());
}
return null;
}
}.execute();
}

答案2

得分: 1

你需要创建一个后端服务器,用于发送特定操作的通知:https://firebase.google.com/docs/cloud-messaging/send-message

尽管你也可以使用Firebase实时数据库与云函数来实现:

https://medium.com/@97preveenraj/firebase-cloud-messaging-fcm-with-firebase-realtime-database-7388493cb869

英文:

You have to create a backend server to send notifications for specific actions: https://firebase.google.com/docs/cloud-messaging/send-message

Although you can use Firebase Realtime Database with Cloud Functions to achieve that also:

https://medium.com/@97preveenraj/firebase-cloud-messaging-fcm-with-firebase-realtime-database-7388493cb869

huangapple
  • 本文由 发表于 2020年9月29日 17:32:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/64116801.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定