使用Azure推送通知重复推送通知

Jig*_*shi 6 azure apple-push-notifications google-cloud-messaging azure-notificationhub

  • 我们正在使用Azure Notification Hub实现针对iOS和Android的推送通知系统.

  • 应用程序启动期间每次都会注册App.通过appname_userid标识的标记注册设备以进行推送通知.例如,Android_1122,其中1122是唯一的用户ID.iPhone设备中的iPhone_1122也是如此.用户可以拥有多个设备,其中推送消息将被传递到具有相同标签的所有设备.

  • 但是,我们正面临着为少数用户提供重复推送通知的问题.每次用户卸载并重新安装应用程序时,都会返回一个新令牌.因此,对于该给定标记,进行多次注册,导致传递到同一设备的重复推送.

  • 也经历了类似下面的链接.但是,并不完全清楚使用创建注册ID REST API的确切含义,该API返回registrationId而不实际创建注册. azure通知集线器 - app uninstall

  • 请提供一些方法来避免重复注册同一设备.

以下是我们用于注册的代码.

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);
}];
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*kar 3

每次用户卸载并重新安装应用程序时,都会返回一个新令牌。因此,对于给定的标签,进行多次注册会导致重复推送到同一设备。

据我了解,一次只有一个工作设备令牌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;
}
Run Code Online (Sandbox Code Playgroud)

使用Google Cloud Messaging,您似乎可以拥有多个有效的 GCM 注册 ID,因此您必须注意这一点。GCM 有一个叫做“ Canonical IDs”的东西:

如果应用程序中的错误触发同一设备的多个注册,则可能很难协调状态,并且最终可能会收到重复的消息。

GCM 提供了一种称为“规范注册 ID”的工具,可以轻松地从这些情况中恢复。规范注册 ID 定义为您的应用程序请求的最后一次注册的 ID。这是服务器向设备发送消息时应使用的 ID。

如果稍后您尝试使用不同的注册 ID 发送消息,GCM 将照常处理该请求,但它将在响应的 Registration_id 字段中包含规范的注册 ID。请务必使用此规范 ID 替换存储在服务器中的注册 ID,因为最终您使用的 ID 将停止工作。