我正在尝试从我的Cloud Firestore中获取一些数据到我的Android应用程序中,但我在使用枚举时遇到了问题。我在Cloud Firestore中为枚举的值保存了一个字符串,但当我将收到的DocumentSnaphot转换为对象时,应用程序崩溃,因为它试图将字符串转换为基于枚举名称(与值不同)的枚举。
我得到的错误是(我发送的值是"NLD"):
java.lang.RuntimeException: Could not deserialize object. Could not find enum value of nl.gemoro.lgs.enums.CountryCode for value "NLD" (found in field 'address.countryCode')
枚举如下所示:
public enum CountryCode {
NETHERLANDS("NLD"),
UNKNOWN("???");
private final String value;
CountryCode(String s) {
value = s;
}
public boolean equalsValue(String otherValue) {
return value.equals(otherValue);
}
public String toString() {
return this.value;
}
}
我使用此方法从Firestore获取数据,并将DocumentSnapshot转换为给定的类:
public static void getAllDocumentsConverted(String collection, final Class convertClass, final OperationCompletedListener listener) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection(collection)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Found " + task.getResult().size() + " documents");
List<Object> list = new ArrayList<>();
List<String> ids = new ArrayList<>();
for (DocumentSnapshot document : task.getResult()) {
list.add(document.toObject(convertClass));
ids.add(document.getId());
}
listener.onOperationComplete(Result.SUCCESS, list, ids);
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
listener.onOperationComplete(Result.FAILED);
}
}
});
}
我不确定是否有人能得到我想要的结果,但我真的希望它能以某种方式工作。
编辑:更清楚:如果枚举只是由枚举名称组成,或者如果名称和值相同,我可以将字符串转换为枚举。
提前谢谢。
发布于 2018-07-28 04:49:53
枚举用例需要精确匹配可能的字符串值,包括大小写。
例如,如果您的国家/地区的值可以为"NLD"
和"US"
,则枚举的结构应如下所示:
public enum CountryCode {
NLD,
US
}
这让Firebase自动将字符串转换为您要转换到的模型的枚举。
注意: Firebase使用<YourEnumType>.valueOf("value-from-doc")
尝试序列化到枚举。在Java语言中不能覆盖枚举的valueOf
,所以这是我们目前能做的最好的将字符串序列化为枚举的方法。
也就是说,如果您这样做,如果您收到的值与您的任何枚举值都不匹配,那么您就会遇到异常。相反,您可以使用Android's @StringDef
annotation。
这使您可以设置允许的值,以便在代码中进行检查和设置,同时允许将实际值设置为任何字符串。如果你从数据库中得到了一个错误的值,这是很有用的。它非常类似于枚举。您还可以使用它为自己指定不同于从Firebase接收到的可能字符串值的常量名称。
您可以按如下方式更改您的CountryCode
枚举:
public class ClassYouAreConvertingTo {
private static final String NETHERLANDS = "NLD";
private static final String UNKNOWN = "???";
@StringDef({NETHERLANDS, UNKNOWN})
@Retention(RetentionPolicy.SOURCE)
private @interface CountryCode {}
private String countryCode;
@CountryCode
public String getCountryCode() {
return this.countryCode;
}
}
现在,可以将国家代码设置为任何值,但Android Studio会尝试确保在检查字符串相等时只使用荷兰和未知常量。当使用不同的值时,你会得到一个红色的下划线(尽管应用程序仍然会编译和运行)。
与枚举路由相比,这是一种更安全、更好的解决方案。接受所有值,但只关心代码中的期望值。
https://stackoverflow.com/questions/49302008
复制相似问题