如何使"过期"的 Firebase 实例 ID 令牌失效



AFAIK,Firebase 实例令牌将在以下 4 种情况下刷新:

  1. 应用删除实例 ID

  2. 应用已在新设备上恢复

  3. 用户卸载/重新安装应用

  4. 用户清除应用数据

假设用户使用令牌 A 作为其"FCM 地址"。每次登录应用程序时,他都会将令牌 A 与该用户的 UUID 一起注册到 Firestore,以便将用户特定的云消息发送给他。当他注销时,系统将向 firestore 发出请求,以删除令牌 A 记录。

现在,当用户重新安装应用时,将刷新实例 ID 并生成新的令牌 B。令牌 A 变得无用。不幸的是,如果用户在卸载之前没有注销,令牌 A 将永远留在火堆中。

有什么解决方法或更明智的方法来处理这种情况吗?

使令牌注册表保持最新需要两个步骤:

  1. 从应用程序代码中删除过期的令牌。
  2. 检查过期的令牌,并在发送消息时将其删除。

删除不再使用的令牌的方法是#1。

第二步是在尝试向其发送消息时收到messaging/invalid-registration-tokenmessaging/registration-token-not-registered响应时从注册表/数据库中删除令牌。函数示例存储库包含一个很好的例子:

admin.messaging().sendToDevice(tokens, payload).then((response) => {
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
// TODO: remove the token from your registry/database
}
}
});
});

上述代码使用 Firebase Admin SDK for Node.js,但相同的逻辑也可以应用于其他平台或通过 HTTPS 端点发送消息时。

正如弗兰克在他的回答中提到的,您可以在发送消息并收到未注册错误时删除它们。

以下是我在使用 C# 注册新注册令牌时如何删除过时的注册令牌。

首先使用实例 ID API,我获得的令牌信息如下:

public async Task<FCMTokenInfo> GetTokenInfoAsync(string token)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://iid.googleapis.com");
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", String.Format("key={0}", "your-authorization-key"));
var uri = $"/iid/info/{token}";
var httpResponse = await client.GetAsync(uri);
var responseStr = await httpResponse.Content.ReadAsStringAsync();
if (httpResponse.StatusCode != HttpStatusCode.OK)
{
//log 400 bad request and do whatever you want
}
var result = JsonConvert.DeserializeObject<FCMTokenInfo>(responseStr);
return result;
}
catch (Exception ex)
{
//log the exception
throw;
}
}

FCMTokenInfo.cs

public class FCMTokenInfo
{
public string Application { get; set; }
public string Subtype { get; set; }
public string Scope { get; set; }
public string AuthorizedEntity { get; set; }
public string Platform { get; set; }
}

然后在数据库中保存注册令牌的服务内部:

//this method gets called when a new token is sent by the javascript web app
public async Task AddTokenAsync(Guid accountId, string token)
{
try
{
//getting TokenInfo of the current token(or refreshed one for that app)
var fcmTokenInfo = await firebaseServices.GetTokenInfoAsync(token);
//adding the current token
dbContext.FcmRegisterationTokens.Add(new FcmRegisterationToken
{
Token = token,
AccountId = accountId,
AddingDate = DateTimeOffset.UtcNow,
Application = fcmTokenInfo.Application,
Subtype = fcmTokenInfo.Subtype,
AuthorizedEntity = fcmTokenInfo.AuthorizedEntity,
Scope = fcmTokenInfo.Scope,
Platform = fcmTokenInfo.Platform
});
var outdatedTokens = await dbContext.FcmRegisterationTokens
.Where(x => x.AccountId == accountId
&& x.Application == fcmTokenInfo.Application
&& x.Platform == fcmTokenInfo.Platform
).ToListAsync();
//remove them
dbContext.FcmRegisterationTokens.RemoveRange(outdatedTokens);
dbContext.SaveChanges();
}
catch (Exception)
{
throw;
}
}

相关内容

  • 没有找到相关文章

最新更新