Generated bindings are not matching Objective-C code

Hello,

During implementation of Firebase Auth features I’ve encountered an issue with Objective-C bindings. Issue is also visible in the moe-bindings repo.

I’m trying to access first element in providerData NSArray available in file FIRUser.h:

@property(nonatomic, readonly, nonnull) NSArray<id<FIRUserInfo>> *providerData;

Which is available in java class FIRUser.java as:

@Generated
@Selector("providerData")
public native NSArray<?> providerData();

Problem is that an NSArray<id<FIRUserInfo>> has changed to NSArray<?>. Trying to cast elements back to ``FIRUserInfo I’m getting an java cast exception.

How MOE is handling NSArray<id<T>> types and how can I access elements of this NSArray in Java?

Thanks in advance!

Did you have bindings to FIRUserInfo? Try generate binding for FIRUserInfo class and add @RegisterOnStartup annotation

I have same FIRUserInfo interface as it is in moe-bindings repo:

Adding @RegisterOnStartup is unfortunately not fixing the issue:

*** Terminating app due to uncaught exception 'java.lang.ClassCastException', reason: 'java.lang.ClassCastException: apple.NSObject cannot be cast to com.myapp.ios.pods.firebase.firebaseauth.protocol.FIRUserInfo

Hi!

Please try this code:

NSArray<?> dataArray = firUser.providerData();
 if (dataArray != null) {
     NSObject data = (NSObject) dataArray.get(0);
     FIRUserInfo userInfo = ObjCRuntime.castToProtocol(data, FIRUserInfo.class);
 }

Best Regards,
Roland

1 Like

Works great, thank you!

I understand, that id type from Objective-C cannot be cast directly using Java casting?

Hi Mateusz,

this can happen, when the Java binding type of the objects passed from ObjC to Java cannot be determined. In this case NSObject is used as a fallback.
This can happen if the object returned is of a private type (i.e. not defined in the headers that were used by Natjgen to generate the binding). We provide these cast*() methods to aid in these situations.

The general algorithm is to use the runtime type of the ObjC object to look for the Java binding type. If that type cannot be found among the Nat/J bindings, we are traversing the ObjC type hierarchy up to NSObject.

It is on the TODO list to generate more precise bindings for NSArray like parameters, but the ObjC -> Java mapping of these generics has a lot of edge cases, and Natjgen will have to be refactored to support all these cases correctly.

Best Regards,
Gergely

1 Like

Mateusz, is there any way you could share a snippet of your implementation code in which you got Firebase Auth to work correctly? I assume the flow allows a user to authenticate with a Google account, but I’m having some trouble with implementation.

Hello Gergely,
I understand it now, thank you for your explanation and help!

Best regards
Mateusz

Hi there!
I’m currently implementing vast Firebase support for our app, including Authentication, Analytics and Realtime Database.
It is quite a lot of work and I will surely create a comprehensive step-by-step tutorial, but now I have some features to deliver on time :slight_smile:

If you are trying to quickly deploy an Firebase Auth with Google Sign-in support - I recommend starting with their “Get started” docs and generate all iOS bindings as they are here: https://github.com/multi-os-engine/moe-bindings/tree/master/firebase-auth

To quickly introduce auth so I’ve also used an FirebaseUI - Android / iOS / Web takeaway views. They work great on each platform!

Surely I can help you with your issues, but I think that it would be better to discuss Firebase-related issues on another topic.

Please feel free to @mention me in your questions :wink:

All the best,
Mateusz

Hi Guys,

I am in trouble with this issue: https://pastebin.com/raw/sX9fZGDr. Can you please help me solve it ?

@matis11: Do you have any suggestion for me ? Thank you in advance !