Дублирование push-уведомлений с использованием push-уведомлений Azure

  • Мы внедряем систему push-уведомлений для iOS и Android с помощью Центра уведомлений Azure.

  • Приложение регистрируется каждый раз при запуске приложения. Устройства регистрируются для push-уведомлений с помощью тегов, идентифицируемых appname_userid. Например, Android_1122, где 1122 - уникальный идентификатор пользователя. То же самое в устройстве iPhone будет iPhone_1122. У пользователя может быть несколько устройств, при этом push-сообщение будет доставлено на все устройства с одним и тем же тегом.

  • Однако есть проблема, с которой мы сталкиваемся, когда повторяющиеся push-уведомления доставляются нескольким пользователям. Каждый раз, когда пользователь удаляет и повторно устанавливает приложение, возвращается новый токен. Таким образом, для этого тега выполняется несколько регистраций, что приводит к дублированию отправки на одно и то же устройство.

  • Также прошли похожие ссылки, подобные приведенной ниже. Но не совсем понятно, что именно подразумевается под использованием REST API для создания идентификатора регистрации, который возвращает registrationId без фактического создания регистрации. концентраторы уведомлений Azure - удаление приложения

  • Предоставьте способ избежать дублирования регистраций для одного и того же устройства.

Ниже приведен код, который мы используем для регистрации.

Устройства iOS

NSString *mobileServicesURL = @"Endpoint=sb://mobilepushnotificationhub.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=XXXXXXXXXXXXXXXXX=";

SBNotificationHub *hub = [[SBNotificationHub alloc] initWithConnectionString:mobileServicesURL notificationHubPath:@"notificationhubname"];

[hub registerNativeWithDeviceToken:token tags:[NSSet setWithObjects:[NSString stringWithFormat:@"iphoneapp_%@", [self getUserID]], nil] completion:^(NSError* error) {
    completion(error);
}];

Android-устройства

private void gcmPush() {
    NotificationsManager.handleNotifications(this, SENDER_ID, MyHandler.class);

    gcm = GoogleCloudMessaging.getInstance(this);

    String connectionString = "Endpoint=sb://mobilepushnotificationhub.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXX=";

    hub = new NotificationHub("notificationhubname", connectionString, this);

    registerWithNotificationHubs();

    // completed Code
}

// Added Method
@SuppressWarnings("unchecked")
private void registerWithNotificationHubs() {
    new AsyncTask() {
        @Override
        protected Object doInBackground(Object... params) {
            try {
                String regid = gcm.register(SENDER_ID);

                Log.e("regid RECEIVED ", regid);
                hub.register(regid, "androidapp_" + WhatsOnIndiaConstant.USERId);

                WhatsOnIndiaConstant.notificationHub = hub;
                WhatsOnIndiaConstant.gcmHub = gcm;

            } catch (Exception ee) {
                Log.e("Exception ", ee.getMessage().toString());
                return ee;
            }
            return null;
        }
    }.execute(null, null, null);
}

person Jigar Joshi    schedule 10.03.2015    source источник


Ответы (1)


Каждый раз, когда пользователь удаляет и повторно устанавливает приложение, возвращается новый токен. Таким образом, для данного тега выполняется несколько регистраций, что приводит к дублированию отправки на одно и то же устройство.

Насколько я понял, для Apple Push Notification Service существует только один токен рабочего устройства (также см. здесь), поэтому у вас не будет проблем с несколькими действительными токенами для одного устройства под iOS, но у вас может быть несколько Azure Notification Hub регистраций для одного токена устройства. Чтобы избежать этого, вы должны проверить, есть ли уже регистрации для конкретного токена устройства, и если да, повторно использовать и очистить их:

ASP.NET WebAPI- Пример серверной части:

// POST api/register
// This creates a registration id
public async Task<string> Post(string handle = null)
{
    // make sure there are no existing registrations for this push handle (used for iOS and Android)
    string newRegistrationId = null;

    if (handle != null)
    {
        var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);

        foreach (RegistrationDescription registration in registrations)
        {
            if (newRegistrationId == null)
            {
                newRegistrationId = registration.RegistrationId;
            }
            else
            {
                await hub.DeleteRegistrationAsync(registration);
            }
        }
    }

    if (newRegistrationId == null) newRegistrationId = await hub.CreateRegistrationIdAsync();

    return newRegistrationId;
}

С Google Cloud Messaging кажется, что у вас может быть несколько рабочих регистрационных идентификаторов GCM, поэтому вы должны позаботиться об этом. В GCM есть что-то под названием "Canonical IDs":

Если ошибка в приложении вызывает несколько регистраций для одного и того же устройства, может быть трудно согласовать состояние, и вы можете получить повторяющиеся сообщения.

GCM предоставляет средство, называемое «каноническими регистрационными идентификаторами», для быстрого восстановления в таких ситуациях. Канонический идентификатор регистрации определяется как идентификатор последней регистрации, запрошенной вашим приложением. Это идентификатор, который сервер должен использовать при отправке сообщений на устройство.

Если позже вы попытаетесь отправить сообщение, используя другой идентификатор регистрации, GCM обработает запрос как обычно, но будет включать канонический идентификатор регистрации в поле registration_id ответа. Обязательно замените регистрационный идентификатор, хранящийся на вашем сервере, на этот канонический идентификатор, так как в конечном итоге используемый вами идентификатор перестанет работать.

person Baris Akar    schedule 13.03.2015
comment
Отлично - ты сделал мой день. Не знал, что GCM использует несколько рабочих токенов устройства! Теперь мои push-сервисы работают! - person Freddy; 09.07.2015
comment
Но этот код будет пропускать уведомления, отправленные между удалением и созданием. - person Ian Warburton; 02.05.2018