我使用推送通知和存储设备令牌,就像我假设其他人一样.首先,我将它们转换为我的应用程序字符串:
NSString *deviceTokenString = [[[token description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
然后我将它们放到我的服务器上,ActiveRecord将它们存储在一个字符变化(255)列中:
Device.where(:token => device_token,:username => username).first_or_create!(:model => model)
我有一个验证,确保没有两个令牌是相同的,我理解应始终如此:
class Device < ActiveRecord::Base belongs_to :user validates_uniqueness_of :token end
但是,我开始看到令牌唯一性的验证错误:
ActiveRecord :: RecordInvalid:验证失败:已经使用了令牌
psql中的手动查询确认设备正在尝试使用其他用户下的表中已有的令牌进行注册.这不应该是不可能的吗?我正在改变令牌截断它们的方式吗?我检查了问题首次出现时我能找到的每个代码示例,每个人似乎都使用我在第一个代码示例中列出的方法.
解决方法
如果有人注销然后使用其他帐户登录,则设备可能会尝试使用其他用户下的表中已有令牌进行注册.
我会在服务器上为用户用户和令牌字符串令牌执行以下操作(假设一次只能有一个用户登录一个设备):
>检查是否有token_string的设备.
>如果没有设备,请为token_string和user创建一个.
>如果有设备且其用户不是用户,请将其用户更新为用户.
关于在设备上将NSData转换为十六进制字符串的方法,您不应该依赖 – [NSData description].最好以编程方式(输入,未测试):
- (NSString *)hexStringForData:(NSData *)data { NSUInteger length = data.length; const char *bytes = data.bytes; NSMutableString *result = [NSMutableString stringWithCapacity:length * 2]; for (int i = 0; i < length; i++) { [result appendFormat:@"%02x",bytes[i] & 0xff]; } return [result copy]; }