Функциональность topic messaging от GCM.
Ваш сервер может отправить сообщение GCM в /topics/{userId}
, и ваше приложение должно подписаться на пользователей, которые используют это устройство. Затем ваше приложение получит сообщение GCM с полем from
, установленным в этой теме, и ваше приложение может отнять его оттуда.
Вы делаете что-то подобное в вашей регистрационной службе GCM:
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
GcmPubSub pubSub = GcmPubSub.getInstance(this);
pubSub.subscribe(token, "/topics/user1", null);
pubSub.subscribe(token, "/topics/user2", null);
Обратите внимание, что вам даже не нужно отправить маркер GCM к службе бэкэнд, потому что он никогда не будет посылать GCM сообщения в частности устройств, только по темам. Поскольку ваше приложение подписано на соответствующие темы, оно получит эти сообщения.
В вашем GCM onMessageReceived вы просто получите личное сообщение и userId и сохраните его где-нибудь.
public void onMessageReceived(String from, Bundle data) {
final int topicsLength = "/topics/".length();
String userId = from.substring(topicsLength);
String privateMessage = data.getString("privateMessage");
saveMessageSomewhere(userId, privateMessage);
}
Затем, когда пользователь входит в ваше приложение, у него есть их сообщения, ожидающие их.
Обратите внимание, что вам нужно генерировать уникальные идентификаторы пользователей. Вы можете запросить приложение у своего бэкэнд-сервиса или просто положиться на UUID.randomUUID()
.
Update
Обратите внимание, что тема GCM должны соответствовать спецификации: /topics/[a-zA-Z0-9-_.~%]+
. Я ошибочно считать разделители разрешены, но если вы используете что-то вроде /topics/users/user1
вы столкнетесь:
java.lang.IllegalArgumentException: Invalid названия темы:/Тема/пользователей/user1
Этих из-за символа разделителя пути в users/user1
. GCM не разрешает иерархию тем, которые могут возникнуть в REST API.
Я обновил приведенный выше код примера, чтобы избежать этой ошибки.
Спасибо за разъяснение и пример :), который сделал трюк – MePo