将 fcm 令牌保存到数据库时,未知字段 "a" 出现在 firestore 中
Unknown field "a" appears in firestore when saving fcm token to database
我正在获取 android 设备令牌并将其保存到 firestore。这在大多数情况下都可以正常工作。现在我遇到了一个无法工作的设备。奇怪的是,我最终在 firestore 中得到了我的模型没有反映的属性,而且我不明白这些属性及其值从何而来。
这是我获取令牌的方法:
public static void updateToken(String userId, FcmToken.Action action) {
if (StringUtils.checkNull(userId)) return;
//FCM
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.w(TAG, "Could not get firebase token. ", task.getException());
return;
}
String token = task.getResult();
Log.i(TAG, "[FCM TOKEN]: " + token);
//Do not ask firebase to write an existing token again,
//this only creates traffic and costs but does not change the database
String storedToken = FcmProvider.loadToken(false);
if (StringUtils.checkNull(storedToken) || !token.equals(storedToken) || action == FcmToken.Action.DELETE) {
FcmToken fcmToken = new FcmToken(token, userId, action);
FcmRepo.getInstance().setToken(fcmToken, documentId -> {
Log.d(TAG, "Token " + action + " successfully");
FcmProvider.saveToken(token);
}, e -> {
Log.d(TAG, "Failed to " + action + " token. " + e);
});
} else {
Log.d(TAG, "Stored token is identical. No update needed");
}
});
}
这是 FcmToken class(我假设我在这里使用字段值的方式有问题,但我不明白结果)
@Getter
@Setter
@IgnoreExtraProperties
public class FcmToken {
private String userId;
private FieldValue fcmToken;
@ServerTimestamp
private Date ut;
public enum Action {SET, DELETE}
public FcmToken(String fcmToken, String userId, Action action) {
this.userId = userId;
if (action == Action.SET) this.fcmToken = FieldValue.arrayUnion(fcmToken);
else if (action == Action.DELETE) this.fcmToken = FieldValue.arrayRemove(fcmToken);
}
}
为了完整起见,这是我用来设置令牌的方法:
public void setToken(@NonNull FcmToken fcmToken, @Nullable OnSetSuccessListener callbackSuccess, @Nullable OnFailureListener callbackFailure) {
getFcmRef().document(fcmToken.getUserId()).set(fcmToken, SetOptions.merge()).addOnCompleteListener(task ->...);
}
现在这就是我的 firestore 中仅供该用户使用的内容:
这必须来自应用程序本身。没有其他方法可以创建此文档:
如果我使用其他设备或模拟器,结果看起来与预期一致。 “a”字段从何而来?为什么赋值给userId,为什么没有fcmToken字段?
问题是,我无法物理访问产生此行为的 phone(Samsung S21 Ultra,Android 12)。我需要在无法访问日志输出的情况下进行调试。
但是我知道任务成功返回(我用另一个版本保存了token字段的错误,有none)。
有什么想法吗?
这通常意味着您没有正确配置 ProGuard,它正在缩小您写入数据库的 类。
您需要防止 ProGuard 修改您用来与数据库交互的 类。请参阅 configuring ProGuard (the link is for the Realtime Database, but the same applies to Firestore), or one of these previous questions about configuring ProGuard for Firebase.
上的 Firebase 文档
我正在获取 android 设备令牌并将其保存到 firestore。这在大多数情况下都可以正常工作。现在我遇到了一个无法工作的设备。奇怪的是,我最终在 firestore 中得到了我的模型没有反映的属性,而且我不明白这些属性及其值从何而来。
这是我获取令牌的方法:
public static void updateToken(String userId, FcmToken.Action action) {
if (StringUtils.checkNull(userId)) return;
//FCM
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.w(TAG, "Could not get firebase token. ", task.getException());
return;
}
String token = task.getResult();
Log.i(TAG, "[FCM TOKEN]: " + token);
//Do not ask firebase to write an existing token again,
//this only creates traffic and costs but does not change the database
String storedToken = FcmProvider.loadToken(false);
if (StringUtils.checkNull(storedToken) || !token.equals(storedToken) || action == FcmToken.Action.DELETE) {
FcmToken fcmToken = new FcmToken(token, userId, action);
FcmRepo.getInstance().setToken(fcmToken, documentId -> {
Log.d(TAG, "Token " + action + " successfully");
FcmProvider.saveToken(token);
}, e -> {
Log.d(TAG, "Failed to " + action + " token. " + e);
});
} else {
Log.d(TAG, "Stored token is identical. No update needed");
}
});
}
这是 FcmToken class(我假设我在这里使用字段值的方式有问题,但我不明白结果)
@Getter
@Setter
@IgnoreExtraProperties
public class FcmToken {
private String userId;
private FieldValue fcmToken;
@ServerTimestamp
private Date ut;
public enum Action {SET, DELETE}
public FcmToken(String fcmToken, String userId, Action action) {
this.userId = userId;
if (action == Action.SET) this.fcmToken = FieldValue.arrayUnion(fcmToken);
else if (action == Action.DELETE) this.fcmToken = FieldValue.arrayRemove(fcmToken);
}
}
为了完整起见,这是我用来设置令牌的方法:
public void setToken(@NonNull FcmToken fcmToken, @Nullable OnSetSuccessListener callbackSuccess, @Nullable OnFailureListener callbackFailure) {
getFcmRef().document(fcmToken.getUserId()).set(fcmToken, SetOptions.merge()).addOnCompleteListener(task ->...);
}
现在这就是我的 firestore 中仅供该用户使用的内容:
这必须来自应用程序本身。没有其他方法可以创建此文档:
如果我使用其他设备或模拟器,结果看起来与预期一致。 “a”字段从何而来?为什么赋值给userId,为什么没有fcmToken字段?
问题是,我无法物理访问产生此行为的 phone(Samsung S21 Ultra,Android 12)。我需要在无法访问日志输出的情况下进行调试。 但是我知道任务成功返回(我用另一个版本保存了token字段的错误,有none)。
有什么想法吗?
这通常意味着您没有正确配置 ProGuard,它正在缩小您写入数据库的 类。
您需要防止 ProGuard 修改您用来与数据库交互的 类。请参阅 configuring ProGuard (the link is for the Realtime Database, but the same applies to Firestore), or one of these previous questions about configuring ProGuard for Firebase.
上的 Firebase 文档