Ошибка InvalidRegistration при попытке использовать залп для отправки push-уведомлений через FCM - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь отправить push-уведомления с помощью Volley в FCM, но они не получены на другой стороне. Ответ, который я получаю от Залпа, следующий:

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

Я новичок в FCM и Volley, и следовал этому руководству . Идея состоит в том, что каждый пользователь подписывается на свой uid в качестве темы, и когда происходит определенное действие, связанное с ним (например, кому-то нравится его фотография), то будет отправлено сообщение с темой в качестве идентификатора.

Каждый раз, когда пользователь входит в приложение, я выполняю следующий код:

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 голосов
/ 19 апреля 2019

Следуя руководству, автор написал место назначения тем в формате, подобном этому /topics/yourTopic, но я подумал, как это организовано в его базе данных или что-то вроде этого.Я не особо задумывался об этом и не копировал часть /topics в свой код, но по этой причине она не прошла.

Мне пришлось изменить это

notification.put("to", receiverId); 

на это:

notification.put("to", "/topics/" + receiverId);
...