1

It's taken me around an hour to debug this issue so I was wondering whether someone would be able to explain what's going on here.

I'm trying to save a Firestore custom object on Android (in Kotlin). Here's a simplified version -

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()

Now if I change the isValid function to throw an exception like so

fun isValid(): Boolean {
    throw TransactionException("No signature found")
}

The save method with throw an error

java.lang.reflect.InvocationTargetException

If I change the function name to simply fun valid() then the save works.

I'm just curious as to why the name of the function matters? I've also tried changing it to something like fun isARadioactiveSpider() and you get the same error.

1 Answer 1

1

A firebase class CustomClassMapper has a method:

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);
    }
}

So reflection is used to serialize methods that look like getters. Later these methods will be invoked using reflection. And this invocation throws some exception, which is hidden in InvocationTargetException

So, to avoid the InvocationTargetException, just check that methods don't throw exceptions, because they are invoked during the serialization

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.