爆炸后没有收到来自firebase的通知的一些消息

时间:2017-04-26 05:13:03

标签: android ruby-on-rails firebase firebase-cloud-messaging

我在android上使用firebase进行通知/推送消息的聊天系统(使用restfull api向firebase发送消息,使用rails& fcm gems)。我正在使用免费帐户firebase。聊天系统很好,没有向一个接收器发送一些消息(例如,几秒钟内有5个或更多消息)。 Fcm回调都已成功发送到后端日志中的firebase (使用rails)。 例如log:

{
  "multicast_id":7122767959146612142,
  "success":1,
  "failure":0,
  "canonical_ids":0,
  "results":[
    {
        "message_id":"0:1493177420664636%a2c0fa75b971369c"
    }
  ]
}

rails中的代码:

def send_message(message, registration_ids, collapse_key)
 fcm = FCM.new(FCM_API_KEY)
 options = { data: message, collapse_key: collapse_key }
 response = fcm.send(registration_ids, options)
end

在android上:

public void onMessageReceived(RemoteMessage message) {
        Log.d("FCM", "onMessageReceived: " + App.getInstance().getGson().toJson(message.getData()));
       // other stuff here
}

但是设备在发送一些消息后没有收到来自firebase的任何通知(没有设备中的firebase通知的输出记录器)。我不知道如何跟踪代码的错误,我认为后端(rails应用程序)和前端(android应用程序)都很好(正常消息成功),我无法检查firebase控制台上的完整登录。我一次可以使用多少信息是否有限制?

示例消息:

{  
   "data": "{
     \"firstname\":\"Ani\",
     \"lastname\":\"Emly\",
     \"image_url\":\"\",
     \"sub_intent_question_id\":\"\",
     \"created_at\":\"2017-04-26T05:29:02.866Z\",
     \"updated_at\":\"2017-04-26T05:29:02.866Z\",
     \"total_unread_count\":0,
     \"unread_counts\": [{\"unread_count\":0,\"id\":\"58c9f7719443790c480003e2\"}],
     \"is_multiple_answer\":false,
     \"content\":\"ggh\",
     \"is_choice\":false,
     \"is_answerable\":true,
     \"user_picture\":\"\",
     \"payload\":null,
     \"user_id\":\"5786ff28150cd4233f003f1d\",
     \"driver_id\":\"582d4b2eedaba85243009d4a\",
     \"options\":[],
     \"id\":\"58c9f7719443790c480003e2\",
     \"username\":\"username\"
   }",
   "category":"reply_object"
}

3 个答案:

答案 0 :(得分:0)

试试这个:

MyFirebaseInstanceIDService

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService  {

    private static final String TAG = "MyFirebaseIIDService";


    @Override
    public void onTokenRefresh() {

        //Getting registration token
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        //Displaying token on logcat
        Log.d(TAG, "Refreshed token: " + refreshedToken);
        sendRegistrationToServer(refreshedToken);



    }


    }




}

MyFirebaseMessagingService

 public class MyFirebaseMessagingService extends FirebaseMessagingService {

        private static final String TAG = "MyFirebaseMsgService";

        /**
         * Called when message is received.
         *
         * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
         */
        // [START receive_message]
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {

            Log.d(TAG, "From: " + remoteMessage.getFrom());

            // Check if message contains a data payload.
            if (remoteMessage != null && remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
                try {
                    JSONObject json = new JSONObject(remoteMessage.getData().toString());
                    sendPushNotification(json);
                } catch (Exception e) {
                    Log.e(TAG, "Exception: " + e.getMessage());
                }
            }

            // Check if message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
    //            sendNotification(remoteMessage.getNotification().getBody());
            }


        }
        // [END receive_message]

        /**
         * Create and show a simple notification containing the received FCM message.
         *
         * @param messageBody FCM message body received.
         */
        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);

            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_app_icon)
                    .setContentTitle("Chetan ram say to you:")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

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

            notificationManager.notify(0 /* _ID of notification */, notificationBuilder.build());
        }

        //this method will display the notification
        //We are passing the JSONObject that is received from
        //firebase cloud messaging
        private void sendPushNotification(JSONObject json) {
            //optionally we can display the json into log
            Log.e(TAG, "Notification JSON " + json.toString());
            try {
                //getting the json data
                JSONObject data = json.getJSONObject("data");

                //parsing json data
                String title = data.getString("title");
                String message = data.getString("message");
                String imageUrl = data.getString("image");

                //creating MyNotificationManager object
                MyNotificationManager mNotificationManager = new MyNotificationManager(getApplicationContext());

                //creating an intent for the notification
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);

                try {
                    if (data.has("details") && data.getJSONObject("details") != null) {
                        Log.e("enter", "enter");
                        intent.putExtra(Constants.AC_LOTTERY_DETAILS, data.getJSONObject("details").toString());
                        intent.putExtra(Constants.FROM_PUSHNOTIFICATION,true);
                    }
                }catch (Exception e)
                {

                }

                //if there is no image
                if (imageUrl.equals("null")) {
                    //displaying small notification
                    mNotificationManager.showSmallNotification(title, message, intent);
                } else {
                    //if there is an image
                    //displaying a big notification
                    mNotificationManager.showBigNotification(title, message, imageUrl, intent);
                }
            } catch (JSONException e) {
                Log.e(TAG, "Json Exception: " + e.getMessage());
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }                    intent.putExtra(Constants.FROM_PUSHNOTIFICATION,true);
                    }
                }catch (Exception e)
                {

                }

                //if there is no image
                if (imageUrl.equals("null")) {
                    //displaying small notification
                    mNotificationManager.showSmallNotification(title, message, intent);
                } else {
                    //if there is an image
                    //displaying a big notification
                    mNotificationManager.showBigNotification(title, message, imageUrl, intent);
                }
            } catch (JSONException e) {
                Log.e(TAG, "Json Exception: " + e.getMessage());
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

MyNotificationManager

public class MyNotificationManager {

    public int ID_BIG_NOTIFICATION = 234;
    public int ID_SMALL_NOTIFICATION = 235;

    private Context mCtx;

    public MyNotificationManager(Context mCtx) {
        this.mCtx = mCtx;
        ID_BIG_NOTIFICATION = getRandom();
        ID_SMALL_NOTIFICATION = getRandom();
    }

    private int getRandom() {
        Random random = new Random();

        return random.nextInt(99999) + 1;
    }

    //the method will show a big notification with an image
    //parameters are title for message title, message for message text, url of the big image and an intent that will open
    //when you will tap on the notification
    public void showBigNotification(String title, String message, String url, Intent intent) {
        PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        mCtx,
                        ID_BIG_NOTIFICATION,
                        intent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
        bigPictureStyle.setBigContentTitle(title);
        bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
        bigPictureStyle.bigPicture(getBitmapFromURL(url));
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx);
        Notification notification;
        notification = mBuilder.setSmallIcon(R.mipmap.ic_launcher).setTicker(title).setWhen(0)
                .setAutoCancel(true)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setStyle(bigPictureStyle)
                .setDefaults(Notification.DEFAULT_VIBRATE|Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS)
                .setSmallIcon(R.drawable.ic_app_icon)
                .setLargeIcon(BitmapFactory.decodeResource(mCtx.getResources(), R.drawable.ic_app_icon))
                .setContentText(message)
                .build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        NotificationManager notificationManager = (NotificationManager) mCtx.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(ID_BIG_NOTIFICATION, notification);
    }

    //the method will show a small notification
    //parameters are title for message title, message for message text and an intent that will open
    //when you will tap on the notification
    public void showSmallNotification(String title, String message, Intent intent) {
        PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        mCtx,
                        ID_SMALL_NOTIFICATION,
                        intent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );


        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx);
        Notification notification;
        notification = mBuilder.setSmallIcon(R.mipmap.ic_launcher).setTicker(title).setWhen(0)
                .setAutoCancel(true)
                .setContentIntent(resultPendingIntent)
                .setContentTitle(title)
                .setSmallIcon(R.drawable.ic_app_icon)
                .setLargeIcon(BitmapFactory.decodeResource(mCtx.getResources(), R.drawable.ic_app_icon))
                .setContentText(message)
                .build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        NotificationManager notificationManager = (NotificationManager) mCtx.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(ID_SMALL_NOTIFICATION, notification);
    }

    //The method will return Bitmap from an image URL
    private Bitmap getBitmapFromURL(String strURL) {
        try {
            URL url = new URL(strURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

AndroidManifest文件

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

        <service
            android:name=".Listeners.MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>

确保将google-services.json文件放入您的应用目录

答案 1 :(得分:0)

这不是关于爆炸的一些消息,但问题是因为我正在使用设备组消息:

def send_message(message, registration_ids, collapse_key)
 fcm = FCM.new(FCM_API_KEY)
 options = { data: message, collapse_key: collapse_key }
 response = fcm.send(registration_ids, options)
end

我使用send/send_notification方法,该方法意味着,将邮件发送到多个注册ID(registration_ids)。 我没有找到任何有关设备组邮件限制的文档,但我发现此文档https://firebase.google.com/docs/cloud-messaging/android/upstream,该文档说的是

  

使用FirebaseMessaging,您可以实现回调onMessageSent   和onSendError检查上游消息的状态。错误   case,onSendError返回带有错误代码的SendException。对于   例如,如果客户端尝试在之后发送更多消息   达到20条信息限制,它会返回   SendException#ERROR_TOO_MANY_MESSAGES。

我现在没有关于我的文档问题的关系,但我在上次测试时获得了20条消息限制。

现在,解决方案是使用参数to而不是registration_ids。关于Data Message

对于rails上的解决方案,我使用send_with_notification_key方法:

fcm = FCM.new(FCM_API_KEY)
options = { data: message }
response = fcm.send_with_notification_key(send_to, options)

答案 2 :(得分:0)

实际上问题似乎是因为collapse_key。

方案: 我使用一些collapse_key在很短的时间内(1分钟)发送了20次推送。 所有这些消息都由设备接收(因为它在线)。 当我尝试发送新推送时,只会收到最后一个推送,这恰好在3分钟后发生(超过20推送限制后)。 因此,该设备每3分钟可以接收1次推送。

仅当我使用collapse_key时才会出现此问题。如果我不使用collapse_key,那么似乎没有限制。 在某些情况下,计数会重置,例如,当设备重新启动或网络发生更改时。