【问题标题】:Send Notification to FCM Using Android App使用 Android 应用程序向 FCM 发送通知
【发布时间】:2019-08-05 07:24:08
【问题描述】:

我想构建客户端和管理员 Android 应用,以便管理员应用向 FCM (API) 发送通知,客户端应用的用户会收到此通知。

因此,我使用 Firebase Admin SDK 通过使用 FCM documentation 将通知从管理应用推送到 FCM,但下一个代码(来自文档)中有一些奇怪的地方

// This registration token comes from the client FCM SDKs.
String registrationToken = "YOUR_REGISTRATION_TOKEN";

// See documentation on defining a message payload.
Message message = Message.builder()
.setNotification(new Notification(
    "$GOOG up 1.43% on the day",
    "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day."))
.setCondition(condition)
.build();


// Send a message to the device corresponding to the provided
    // registration token.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
 System.out.println("Successfully sent message: " + response);

由于send(RemoteMessage) 接受RemoteMessage 而不是Message 对象,所以我如何修改前面的代码以使用RemoteMessage 对象发送通知

【问题讨论】:

  • 您在标题中提到了 SVM。这是我不熟悉的首字母缩写词。这是什么意思?
  • 您使用 android 进行了标记,但 Firebase Admin SDK 不适合在客户端应用程序代码中使用(因为它授予其运行的进程无限制地访问您的 Firebase 项目)。你想在哪里运行这段代码?

标签: android firebase firebase-cloud-messaging


【解决方案1】:

使用我的代码就像魅力一样工作: 向特定用户发送通知并管理通知的点击。

implementation 'com.google.firebase:firebase-messaging:20.1.3'
implementation 'com.google.firebase:firebase-analytics:17.2.3'

清单

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="default_channel_id" />

    <service
        android:name=".FCMService" >
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

活动

  1.  project setting > cloud messaging > server key
      AUTH_KEY = server key

  2.  token id of a particular device is 
      String device_token = FirebaseInstanceId.getInstance().getToken();

发送通知时

  new Thread(new Runnable() {
        @Override
        public void run() {
            pushNotification(senderName + " : " + message);

        }
    }).start();

  private void pushNotification(String message) {
    JSONObject jPayload = new JSONObject();
    JSONObject jNotification = new JSONObject();
    JSONObject jData = new JSONObject();
        try {
            // notification can not put when app is in background
            jNotification.put("title", getString(R.string.app_name));
            jNotification.put("body", message);
            jNotification.put("sound", "default");
            jNotification.put("badge", "1");
            jNotification.put("icon", "ic_notification");

//            jData.put("picture", "https://miro.medium.com/max/1400/1*QyVPcBbT_jENl8TGblk52w.png");

            //to token of any deivce
            jPayload.put("to", device_token);

            // data can put when app is in background
            jData.put("goto_which", "chatactivity");
            jData.put("user_id", mCurrentUserId);

            jPayload.put("priority", "high");
            jPayload.put("notification", jNotification);
            jPayload.put("data", jData);

            URL url = new URL("https://fcm.googleapis.com/fcm/send");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Authorization", "key=" + AUTH_KEY);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            // Send FCM message content.
            OutputStream outputStream = conn.getOutputStream();
            outputStream.write(jPayload.toString().getBytes());

            // Read FCM response.
            InputStream inputStream = conn.getInputStream();
            final String resp = convertStreamToString(inputStream);

        } catch (JSONException | IOException e) {
            e.printStackTrace();
        }
    }

    private String convertStreamToString(InputStream is) {
        Scanner s = new Scanner(is).useDelimiter("\\A");
        return s.hasNext() ? s.next().replace(",", ",\n") : "";
    }

添加服务类

    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.media.RingtoneManager;
    import android.net.Uri;
    import android.util.Log;

    import androidx.annotation.NonNull;
    import androidx.core.app.NotificationCompat;

    import com.google.android.gms.tasks.OnCompleteListener;
    import com.google.android.gms.tasks.Task;
    import com.google.firebase.iid.FirebaseInstanceId;
    import com.google.firebase.iid.InstanceIdResult;
    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;

    public class FCMService extends FirebaseMessagingService {
        String goto_which, user_id;

        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            super.onMessageReceived(remoteMessage);
            Log.d("ff", "messddda recice: " + remoteMessage.getNotification().getTicker());
            String title = remoteMessage.getNotification().getTitle();
            String body = remoteMessage.getNotification().getBody();

            if (remoteMessage.getData().size() > 0) {
                goto_which = remoteMessage.getData().get("goto_which").toString();
                user_id = remoteMessage.getData().get("user_id").toString();
                Log.d("ff", "messddda send: " + goto_which);
            }
            sendnotification(title, body, goto_which, user_id);
        }

        private void sendnotification(String title, String body, String goto_which, String user_id) {
            Intent intent = new Intent(this, MainActivity.class);
            intent.putExtra("goto_which", goto_which);
            intent.putExtra("user_id", user_id);

            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
            Uri defaultsounduri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder nbuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher_background)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setAutoCancel(true)
                    .setSound(defaultsounduri)
                    .setContentIntent(pendingIntent);

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(0, nbuilder.build());


            FirebaseInstanceId.getInstance().getInstanceId()
                    .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
                        @Override
                        public void onComplete(@NonNull Task<InstanceIdResult> task) {
                            if (!task.isSuccessful()) {
                                Log.w("f", "getInstanceId failed", task.getException());
                                return;
                            }

                            // Get new Instance ID token
                            String token = task.getResult().getToken();

                        }
                    });

        }
    }

管理点击通知:

它调用启动器活动,因此您可以在启动器活动中管理特定活动的调用

您的启动器活动看起来像

 if (getIntent().getExtras() != null) {
        String goto_which = getIntent().getStringExtra("goto_which");
        String chatUser = getIntent().getStringExtra("user_id");

        if (goto_which.equals("chatactivity")) {
            Intent chatIntent = new Intent(getBaseContext(), ChatActivity.class);
            chatIntent.putExtra("user_id", chatUser);
            startActivity(chatIntent);
        } else if (goto_which.equals("grpchatactivity")) {
            Intent chatIntent = new Intent(getBaseContext(), GroupChatActivity.class);
            chatIntent.putExtra("group_id", chatUser);
            startActivity(chatIntent);
        }
    }

【讨论】:

    【解决方案2】:

    您似乎正在尝试将 Firebase Admin SDK 与适用于 Android 的 Firebase Cloud Messaging SDK 混合使用。这是不可能的。

    任何使用 Admin SDK 的进程都被授予对您的 Firebase 项目的完全、无限制的访问权限。因此,如果您将其放在客户端应用程序中,使用该应用程序的每个人都可以向您的任何用户发送 FCM 消息,而且:列出所有这些用户、删除您的整个数据库、覆盖您的 Cloud Functions 等。为此Firebase Admin SDK 应该/只能在受信任的环境中使用的原因,例如您的开发机器、您控制的服务器或 Cloud Functions。

    要通过 Firebase 云消息传递设备发送消息,您始终需要有一个受信任的环境,在 FCM 文档中通常称为 应用服务器

    当您在该受信任的环境中运行 Admin SDK 时,您可以调用 FirebaseMessaging.getInstance().send() method,它将 build() 返回的 Message 作为其参数。

    另见:

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      相关资源
      最近更新 更多