如何处理在生成新令牌和 vendorId 后仍然有效的旧 iOS 通知令牌?

问题描述

我正在使用 Azure 通知中心发送远程通知,目前仅向 iOS 发送。

我最初意识到我的设备收到了 5 个相同通知事件的通知。我检查并调试了我的代码,它确实正确地检查了提供的要注册的令牌是否尚未注册

然后我检查了我的数据库并意识到我没有重复,而是一个设备和用户帐户的 5 个不同的设备令牌。每次我卸载然后在我的设备上重新安装应用程序时,它们都会生成

鉴于此,我会认为当卸载应用程序时,之前生成的令牌会被苹果系统设为无效?我认为这是因为在重新安装时,会生成一个新的令牌,与之前的令牌不同。为什么旧令牌仍然有效;这样的用例是什么。

对于 iOS 开发来说似乎 other people are having this issueincluding Android 也是如此。

使用 vendorId 来识别设备是毫无意义的,as some are finding out,它也会在全新安装时发生变化。当我卸载应用程序并重新安装时,我会得到一个新的 vendorId 和一个新的通知令牌,使之前的令牌仍然有效,从而打开了接收多个通知实例的能力(因为后端无法将新的两个值匹配到数据库中存在的任何内容)。

对此有什么建议吗?我对此完全迷失了?

更新:我当然需要一个用户一次拥有多个设备令牌,以防他们在多台设备上登录

解决方法

您基本上必须自己识别设备,方法是使用 UUID 将 ID 保存到钥匙串中。钥匙串,因为数据在多次安装后仍然存在。

以下是使用 Locksmith 的快速实现:

import UIKit
import Locksmith


class Keychain
{
    private static let AccountName = "MyAppName";
    private static let CustomDeviceIdKey = "CustomDeviceIdKey";
    
    private static func AccountData() -> Dictionary<String,Any>?
    {
        return Locksmith.loadDataForUserAccount(userAccount: AccountName)
    }
    
    private static func GenerateCustomDeviceId() -> Bool
    {
        do{
            try Locksmith.saveData(data: [CustomDeviceIdKey: UUID().uuidString],forUserAccount: AccountName)
            return true
        }catch{
            print("Failed to save custom device id: \(error.localizedDescription)")
            return false
        }
    }
    
    static func CustomDeviceId() -> String
    {
        let data = AccountData()
        if let result = data?[CustomDeviceIdKey] as? String{
            return result
        }else{
            if GenerateCustomDeviceId(){
                return CustomDeviceId()
            }
            return ""
        }
    }
}

然后你就走了:

func SomeMethodThatNeedsDeviceId(){
    var customDeviceIdThatPersistsOverInstalls = Keychain.CustomDeviceId()
}

这就是您用来代替 VendorId 的内容

,

从 Azure 通知中心的角度回答,我们将每个设备 ID 视为一个有效的设备 ID,并且只有在我们尝试推送到该设备并且 Apple 向我们提供设备已过期的响应时,才会阻止未来发送针对该设备/无效的。因此,由于重新安装,我们无法了解不同的设备 ID 是否属于同一设备。

这与单个通知可能多次获取相同设备 ID 的情况不同。在这种情况下,我们的服务具有重复数据删除逻辑以防止重复通知。