FCM Migration Guide for APEX

Essential guidance for migrating from FCM Legacy to HTTP v1 in Salesforce Apex using expert strategies for a seamless transition and better performance.

Firebase Cloud Messaging (FCM) architecture for push notifications in mobile and web applications
Key takeaways
  • 1 Migration Benefits: Moving from FCM Legacy to HTTP v1 also adds reliability, security and offers more features at the same time. HTTP v1 used to support OAuth 2. 0 for secure communication and also has some characteristics such as the ability to batch messages.
  • 2 Updated Implementation: When transitioning to HTTP v1, there are some modifications like structure of payloads, shift in endpoints, and changes in the methods of authentication. Some of the known methods for proper handling of responses and errors will be discussed below.
  • 3 Secure Credential Storage: Storing FCM credentials in Salesforce Custom Metadata Types is safe and convenient at the same time. This helps in appealing the problem of hard-coding of sensitive information and makes security consistent across environments.

FCM, or Firebase Cloud Messaging, has always been a leading choice for reaching your users with notifications and messages regardless of the platform. Nevertheless, the technology is not limited to communication methods; instead, the methods and protocols are also moving along with the evolution of the technology. Hence, following the development, HTTP v1 is implemented instead of the IPv0 FCM. Replacing the old protocol with a new one will help us to reach higher reliability, better security, and, at the same time, include some extra functions. In this blog, we will discuss migration of legacy FCM to HTTP v1 using apex in salesforce.

Why Migrate to HTTP v1?

Migrating to HTTP v1 offers several compelling advantages:

  • Improved Reliability: HTTP v1 uses the channels with greater stable performance for reliability in delivering the messages to the FM servers that are Cloud Messaging.
  • Enhanced Security:  HTTP v1 is focusing on authentication that is using OAuth 2.0, in order to ensure secure interaction of Salesforce environment and FCM servers.
  • Support for New Features: HTTP v1 creates new features: the message batching , by using it, the transmission of multiple messages in a single data package helps expedite such processes.

Understanding OAuth 2.0 Authentication for HTTP v1

Since the authentication mechanism is one of the most significant changes between FCM Legacy and HTTP v1, let’s briefly discuss how OAuth 2.0 plays into the migration.

FCM Legacy utilized a simple server key which was sent as a static authorization header with each request. Compared to the security of OAuth 2.0 discussed below this is much simpler but comes at the cost of flexibility and security. In particular, the server key grants the recipient of the key full access to send messages as any user in the project scope without additional safeguards or expiry built into the protocol.

Using OAuth 2.0 this is replaced by a short lived access token generated from the service account credentials which is signed with a private key belonging to the service account itself rather than a permanent server key.

In practice, this means that the Salesforce Apex code will need to generate a JSON Web Token signed with the service account’s private key and use that to fetch an access token from Google’s OAuth token endpoint. This access token is what gets sent as the Authorization header for your FCM request. But unlike a legacy server key, this token will only be valid for a predefined period (usually about an hour) after which the Salesforce code will need to refresh it using the same process.

While this adds complexity and operational overhead, this is the main security innovation which HTTP v1 brings to the table. Put another way, while a leaked server key grants permanent access to the project, with OAuth 2.0, the security breach would only result in a limited access window.

Sending Push Notification using the FCM Legacy

Push notification from FCM

Currently, developers comprising the FCM Legacy team place the JSON containing the packet of necessary details, for instance, the recipient’s device ID, within the phone’s device memory. The device ID is identified through settings, under a hidden ID field. And it sends an HTTP request to the FCM endpoint (HTTP includes appropriate headers and payload) with the content above

Here’s a simplified example of how notifications might have been sent using FCM Legacy in Salesforce Apex:

Illustration of Firebase Cloud Messaging (FCM) for real-time push notifications in Android, iOS, and web applications

Migrating to HTTP v1

In order to migrate from FCM Legacy to HTTP v1, we have to perform different sets of variation to the implementation, for example payload structure adjustment, endpoints adjustment, authentication/authorization method changing and response/error handling.

Key features of Firebase Cloud Messaging (FCM) for secure and scalable push notifications

Methods to generate JWT and Access Token

Here are the methods that you can use to generate the JWT and Access token required for the FCM HTTP V1 API:

Firebase Cloud Messaging (FCM) implementation workflow for sending push notifications to Android, iOS, and web applications

Handling Token Expiration and Refresh Logic

Because HTTP v1’s access tokens are short-lived, your Apex implementation should have logic in place to refresh them rather than requesting a brand new token for every single notification send, which would be very resource intensive and wasteful to your API call limit.

One approach is to cache the access token, along with its expiration time, after initial creation, and reusing it for subsequent FCM requests. If the cached token is expired or about to expire, you will need logic in place to generate a new JWT and access token before attempting to send any messages.

Depending on your implementation, you may want to store the cached token somewhere more permanent for your Apex transactions to access. Using either a custom setting or platform cache in Salesforce will allow you to persist the token rather than recreating it on every request. In this case, I would recommend using the platform cache as the preferred method to store the token, as it is optimized for this sort of short-term storage, and will not incur extra overhead writing to a database.

Without this method in place, your integration could either generate exponentially larger amounts of unnecessary tokens, or fail outright when an expired token is passed to FCM’s API endpoint.

Comparing Changes:

Here’s a comparison of changes between FCM Legacy and HTTP v1:

FCM LegacyHTTP v1
Payload Structure{    “to”: “DEVICE_ID”,    “notification”: {        “title”: “Title”,        “body”: “Body”    }}
{    “message”: {        “token”: “DEVICE_ID”,        “notification”: {            “title”: “Title”,            “body”: “Body”        }    }}
Endpointhttps://fcm.googleapis.com/fcm/sendhttps://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send
Authorizationkey= YOUR_LEGACY_SERVER_KEYBearer YOUR_ACCESS_TOKEN
Response{    “multicast_id”: 1591429548771005280,    “success”: 0,    “failure”: 2,    “canonical_ids”: 0,    “results”: [        {            “error”: “NotRegistered”        },        {            “error”: “NotRegistered”        }    ]}On Success:{    “name”:  “projects/[your-project-id]/messages/[messageId]”
}

On Failure:{    “error”: {        “code”: 401,        “message”: “Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.”,        “status”: “UNAUTHENTICATED”    }}

Common Errors During Migration and How to Resolve Them

There are several common pitfalls associated with the transition from FCM Legacy to HTTP v1, the awareness of which can help avoid hours of debugging:

An “UNAUTHENTICATED” error on the response, as depicted in the provided comparison, almost always stems from an issue related to the OAuth token, which could be expired, improperly formed or the JWT to which it was issued was signed incorrectly. It is useful to check if the claims of the JWT, including the scope for FCM and the temporal claim (the expiration) match the expectations of Google’s OAuth endpoint.

The structure of the payload in the requests is different since the HTTP v1 standard utilizes a message object to house the contents of the notification, as opposed to the flattened structure of the FCM Legacy API. As a result, any requests utilizing the latter convention will be denied, as opposed to being partially successful – therefore, it is crucial to ensure that the request body conforms to the HTTP v1 standard.

The project ID in the URL of the endpoint should also be checked for correctness since the HTTP v1 uses the Firebase project ID in the URL path, as opposed to the other Google APIs that utilize query string parameters for the same purpose.

Finally, the Remote Site Settings or the Named Credentials in the Salesforce org must be configured to permit the outbound requests to Google’s OAuth token issuer and the FCM HTTP v1 endpoint. The transition from the sandbox environment, which is more lenient in its security policies, to the production environment, which requires the explicit permission for each external domain, can cause the unexpected failures in the former environment.

Custom Metadata for Storing Credential

Keeping your credentials private is very recommended both project id, client id in particular private key securedly. To fulfill this objective while using Salesforce, Custom Metadata Types which help to create new, descriptive types and thereby increasing the information much more. With Custom Metadata Types storage and managing the custom data can be done seamlessly without any deployment issues when working between environments.

To store the credentials in Custom Metadata:

  • 1.  Define Custom Metadata Type:
    • Go to Setup > Custom Metadata Types.
    • Let us create a new Custom Metadata Type like “FCM_Settings”.
    • Define the fields <br> <i>for <br> project ID, client ID and private <br> key</i><br>
  • 2. Store Credentials:
    • Set a new space for “FCM_Settings” that the custom metadata type will be used.
    • In the fields please fill out the website, which address it is located and the phone number it has.
  • 3. Retrieve Credentials in Code:
    • Investigate Apex to declare the Custom Metadata records and pull the credentials as necessary.

Here’s an example of how to retrieve credentials in Apex:

      FCM_Settings__mdt firebaseConfig = [
            SELECT Client_Id__c, Private_Key_HTTP_V1__c, Project_Id__c
            FROM FCM_Settings__mdt
            LIMIT 1
        ];

        String privateKey = firebaseConfig.Private_Key_HTTP_V1__c;
        String clientId = firebaseConfig.Client_Id__c;
        String projectId = firebaseConfig.Project_Id__c;

// Query Custom Metadata records

Use Custom Metadata to store the password instead of hard-coding so that any malicious person who views the code cannot access it.

Conclusion

Migrating from FCM Legacy to HTTP V1 in Salesforce Apex is crucial for utilization of the latest features, making the system more reliable and secured. Bearing this in mind, through implementation of the steps described in this blogpost and editing your code according to the requirements, you would successfully update your HTTP v1 and easily send stimulating notifications to your users with a sense of confidence. Anyway, through the use of the Custom Metadata Types to store the credentials the information is going to be securely managed within the Salesforce platform.

Frequently Asked Questions

Google has been phasing out the legacy FCM API, so it’s best treated as a temporary bridge rather than a long-term option. Running both during a migration period is possible while testing, but the legacy endpoint shouldn’t be relied on for production use going forward.

HTTP v1 requires a service account with the appropriate Firebase Cloud Messaging permissions, which is different from the simple server key used by FCM Legacy. If your project doesn’t already have one, it needs to be created through the Firebase console before implementing HTTP v1.

Access tokens generated through this flow are typically valid for one hour. Implementations should check the token’s expiration before each use and refresh it proactively rather than waiting for a request to fail with an authentication error.