调试这个问题花了我大约一个小时的时间,所以我想知道是否有人能够解释这里发生的情况。
我正在尝试在Android(在Kotlin中)上保存Firestore自定义对象。这是简化版-
class MockTransaction {
val endpoint: String = "mockTransactions"
var fromAddress: String = ""
var toAddress: String = ""
var amount: Double = 0.0
constructor() {}
constructor(from: String, to: String, amount: Double) {
this.fromAddress = from
this.toAddress = to
this.amount = amount
}
fun isValid(): Boolean {
return true
}
fun save() {
val db = FirebaseFirestore.getInstance()
db.collection(endpoint).add(this).addOnCompleteListener {
Log.d("TX", it.isSuccessful.toString() )
Log.d("TX", it.exception.toString())
}
}
}
val tx = MockTransaction("Alice", "Bob", 100.0)
tx.save()
现在,如果我更改isValid
函数以引发类似这样的异常
fun isValid(): Boolean {
throw TransactionException("No signature found")
}
抛出错误的保存方法
java.lang.reflect.InvocationTargetException
如果我将函数 name 更改为简单的fun valid()
,则保存有效。
我只是想知道为什么函数名称很重要?我也尝试将其更改为fun isARadioactiveSpider()
之类的内容,但您遇到相同的错误。
答案 0 :(得分:1)
firebase类CustomClassMapper
具有以下方法:
private static boolean shouldIncludeGetter(Method method) {
if (!method.getName().startsWith("get") && !method.getName().startsWith("is")) {
return false;
} else if (method.getDeclaringClass().equals(Object.class)) {
return false;
} else if (!Modifier.isPublic(method.getModifiers())) {
return false;
} else if (Modifier.isStatic(method.getModifiers())) {
return false;
} else if (method.getReturnType().equals(Void.TYPE)) {
return false;
} else if (method.getParameterTypes().length != 0) {
return false;
} else {
return !method.isAnnotationPresent(Exclude.class);
}
}
因此,反射用于序列化类似于getter的方法。稍后,将使用反射调用这些方法。并且此调用引发了一些异常,该异常隐藏在InvocationTargetException
因此,为避免使用InvocationTargetException
,只需检查方法是否抛出异常,因为它们是在序列化期间调用的