firebase / firebase-admin-java

Firebase Admin Java SDK

Home Page:https://firebase.google.com/docs/admin/setup

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[FR] - Need a setter to set FCM host for Functional tests/Service Level tests.

yashjain12yj opened this issue · comments

Summary:
I recently integrated FCM SDK to send Push Notifications. The integration was very simple and smooth but while I started writing Functional Tests, I got to know that I can't give FCM host while constructing a FcmMessaging object. The FCM_URL is hardcoded in the FirebaseMessagingClientImpl class, which is restricting me from writing functional tests.

Solution:
While constructing the FcmMessaging object or while initializing FirebaseApp there can be an option to pass the FCM host. If the host is not passed then the default hardcoded host must be used.

Describe alternatives you've considered
Currently, due to this, I'm blocked from writing FTs. I'm currently only dependent on UTs

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

I have created this PR for the above-mentioned request.
@lahirumaramba Could you please check once?

Hey @yashjain12yj, might be too late for you since it's currently november but I implemented a work-around for this issue using reflection.

/**
   * Override the internal fcm.googleapis.com URL with a gateway URL. This function is needed due to
   * the FirebaseClient interface missing a property to configure the FCM url.
   *
   * @throws Exception ReflectionBased errors, could be encountered once the {@link FirebaseClient}
   *     interface is changed.
   */
  private void overrideFcmUrl() throws Exception { 
    var instance = FirebaseMessaging.getInstance();
    var clientSupplierField = instance.getClass().getDeclaredField("messagingClient");
    clientSupplierField.setAccessible(true);
    var clientSupplier = (Supplier<?>) clientSupplierField.get(instance);
    var messager = clientSupplier.get();
    var urlField = messager.getClass().getDeclaredField("fcmSendUrl"); 
    setFinal(messager, urlField, gatewaySendUrl); 
  }

  /**
   * Helper function to override private final fields in Objects.
   *
   * @param instance Object that contains {@link Field}
   * @param field Field that should be changed
   * @param newValue any value
   * @throws Exception ReflectionBased errors, could be encountered once the {@link FirebaseClient}
   *     interface is changed
   */
  private void setFinal(Object instance, Field field, Object newValue) throws Exception { 
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
    field.set(instance, newValue);
  }

This effectively rewrites the fcmSendUrl which can then be used for testing. Hope this is of any help!

+1, we are also experiencing the issue described in this ticket

Any update on this issue? The PR is waiting for review. Thanks!