Unrecognized selector sent to instance (messaging:didRefreshRegistrationToken)

i’m trying to implement the interface FIRMessagingDelegate like following:

FIRMessaging.messaging().setDelegate(new FIRMessagingDelegate() {
        @Override
        public void messagingDidRefreshRegistrationToken(FIRMessaging messaging, String fcmToken) {
            Foundation.NSLog("New Token is %s" , fcmToken);
        }

        @Override
        public void messagingDidReceiveMessage(FIRMessaging messaging, FIRMessagingRemoteMessage remoteMessage) {

        }
    });

and I’m getting the exception messaging:didRefreshRegistrationToken:]: unrecognized selector sent to instance 0x60800000f4b0
org.moe.natj.objc.ObjCException. This exception occurs only when i run the app for first time.

The following is the generated binding interface i need to implement and pass to “setDelegate” (which is looking weird)

@Generated
@Library("FirebaseMessaging")
@Runtime(ObjCRuntime.class)
@ObjCProtocolName("FIRMessagingDelegate")
public interface FIRMessagingDelegate {
	@Generated
	@IsOptional
	@Deprecated
	@Selector("applicationReceivedRemoteMessage:")
	default void applicationReceivedRemoteMessage(
			FIRMessagingRemoteMessage remoteMessage) {
		throw new java.lang.UnsupportedOperationException();
	}

	@Generated
	@IsOptional
	@Selector("messaging:didReceiveMessage:")
	default void messagingDidReceiveMessage(FIRMessaging messaging,
			FIRMessagingRemoteMessage remoteMessage) {
		throw new java.lang.UnsupportedOperationException();
	}

	@Generated
	@Selector("messaging:didRefreshRegistrationToken:")
	void messagingDidRefreshRegistrationToken(FIRMessaging messaging,
			String fcmToken);
}

It is an interface for this protocol

Also I’m wondering why the plugin generates a body for interface method ?!
is this just for suppressing “optional” methods or something went wrong as a bug ?

Hi,

You guessed right: we are using interface methods with a body to handle the optional methods feature in ObjC protocols.

About setting the delegate: Our Nat/J processor (that runs during compilation as part of Retrolambda) should automatically copy the required @Selector annotations from the interface definition to your anonymous class. However, we have seen some cases where this does not happen. You can double check with a class decompiler in the retrolambda output under build/moe.

If this is the case, please let me know. The workaround is to copy the necessary @Selector annotation to your anonymous class manually.

Best Regards,
Gergely

I made a new separate class that implements FIRMessageDelegate instead of making anonymous class
(as i couldn’t decompile the entire class file)

public class SimpleFIRMessagingDelegate implements FIRMessagingDelegate {
@Override
public void messagingDidRefreshRegistrationToken(FIRMessaging messaging, String fcmToken) {
Foundation.NSLog("new token is %s" , fcmToken);
}
}

and here is the decompilation of the class file located in build/moe/main/retro/output/my/package/name/

package com.example.maittarek.testpods; 
import com.example.maittarek.testpods.firebasemessaging.protocol.FIRMessagingDelegate;
public class SimpleFIRMessagingDelegate implements FIRMessagingDelegate {
 public SimpleFIRMessagingDelegate() {
 }
}

seems that the selector annotation was removed even the body

Even with copying the selector i got the same exception & the decompiled file does not contain it.

Proguard was eating the FIRMessagingDelegate interface methods
Now it works after using a directive to keep this interface and my implementation