尝试使用Volley通过FCM发送推送通知时发生InvalidRegistration错误

时间:2019-04-19 01:11:35

标签: android push-notification firebase-cloud-messaging android-volley

我正在尝试使用Volley将推播通知发送给FCM,但在另一侧却没有收到它们。我从Volley那里得到的答复就是这个

{"multicast_id":7351526324257141941,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

我是FCM和Volley的新手,并且一直关注this guide。这个想法是,每个用户都将其uid订阅为主题,并且当发生与他们相关的特定操作(例如,某人喜欢他们的照片)时,就会发送一条以该主题作为其ID的消息。

无论何时用户登录到应用程序,我都会执行以下代码:

val uid = FirebaseAuth.getInstance().uid
val userRef = FirebaseDatabase.getInstance().getReference("/users/$uid/services/firebase-token")
userRef.setValue(token)
FirebaseMessaging.getInstance().subscribeToTopic(uid)

我目前正在测试中,因此我要发送的消息非常普通。这些是应该执行的功能。

static void sendMessageTopic(String receiverId, String initiatorId, String post, Activity activity) {

        String NOTIFICATION_TITLE = "some title";

        String NOTIFICATION_MESSAGE = "This is the message";


        JSONObject notification = new JSONObject();
        JSONObject notificationBody = new JSONObject();
        try {
            notificationBody.put("title", NOTIFICATION_TITLE);
            notificationBody.put("message", NOTIFICATION_MESSAGE);

            notification.put("to", receiverId);
            notification.put("data", notificationBody);
        } catch (
                JSONException e) {
            Log.e("notificationStuff", "onCreate: " + e.getMessage());
        }

        sendNotification(notification, activity);
    }

然后:

static void sendNotification(JSONObject notification, Activity activity) {

        String FCM_API = "https://fcm.googleapis.com/fcm/send";
        String serverKey =
                "AAAAA6gibkM:APA91bG8UUtfNFwNLI6-Peu_KsbpTskmjutdJDyHq-qi5fj2UdCcjIVRCO5PlhZUNfJdeyW4-3oznOxMDWdjpfSAnpltlvtBFCoM_vir7pQLKbxc_aDzWJPs8xu27CADbMkHkq5tKgT7";

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(FCM_API, notification,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.i("notificationStuff", "onResponse: " + response.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(activity, "Request error", Toast.LENGTH_LONG).show();
                        Log.i("notificationStuff", "onErrorResponse: Didn't work");
                    }
                }){
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Authorization", "key=" + serverKey);
                params.put("Content-Type", "application/json");
                return params;
            }
        };
        MySingleton.getInstance(activity.getApplicationContext()).addToRequestQueue(jsonObjectRequest);
    }

单身人士:

public class MySingleton {
    private  static MySingleton instance;
    private RequestQueue requestQueue;
    private Context ctx;

    private MySingleton(Context context) {
        ctx = context;
        requestQueue = getRequestQueue();
    }

    public static synchronized MySingleton getInstance(Context context) {
        if (instance == null) {
            instance = new MySingleton(context);
        }
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        }
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }
}

然后是我用来接收消息的方法:

public class MyJavaFCM extends FirebaseMessagingService {

    private final String ADMIN_CHANNEL_ID ="admin_channel";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        final Intent intent = new Intent(this, MainActivity.class);
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        int notificationID = new Random().nextInt(3000);

      /*
        Apps targeting SDK 26 or above (Android O) must implement notification channels and add its notifications
        to at least one of them. Therefore, confirm if version is Oreo or higher, then setup notification channel
      */
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            setupChannels(notificationManager);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this , 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
                R.drawable.profile_icon);

        Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
                .setSmallIcon(R.drawable.logo_fallback)
                .setLargeIcon(largeIcon)
                .setContentTitle(remoteMessage.getData().get("title"))
                .setContentText(remoteMessage.getData().get("message"))
                .setAutoCancel(true)
                .setSound(notificationSoundUri)
                .setContentIntent(pendingIntent);

        //Set notification color to match your app color template
        notificationBuilder.setColor(getResources().getColor(R.color.colorPrimaryDark));
        notificationManager.notify(notificationID, notificationBuilder.build());
    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    private void setupChannels(NotificationManager notificationManager){
        CharSequence adminChannelName = "New notification";
        String adminChannelDescription = "Device to devie notification";

        NotificationChannel adminChannel;
        adminChannel = new NotificationChannel(ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_HIGH);
        adminChannel.setDescription(adminChannelDescription);
        adminChannel.enableLights(true);
        adminChannel.setLightColor(Color.RED);
        adminChannel.enableVibration(true);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(adminChannel);
        }
    }
}

唯一的错误提示是我一开始就添加了该消息,但是我不确定该如何处理(试图阅读该消息,但对所讲的内容不甚了解,不知道这是否与我的具体情况有关。

1 个答案:

答案 0 :(得分:0)

在遵循指南时,作者以类似于/topics/yourTopic的格式写了主题目的地,但是我认为这是在他的数据库或类似的东西中组织起来的方式。我并没有考虑太多,也没有将/topics部分复制到我的代码中,但这就是它没有通过的原因。

我不得不更改

notification.put("to", receiverId); 

对此:

notification.put("to", "/topics/" + receiverId);
相关问题