Migrate from Legacy HTTP to HTTP v1

Apps using the FCM legacy HTTP API should consider migrating to the HTTP v1 API using the instructions in this guide. The HTTP v1 API has these advantages over the legacy API:

  • Better security via access tokens The HTTP v1 API uses short-lived access tokens according to the OAuth2 security model. In the event that an access token becomes public, it can only be maliciously used or an hour or so before it expires. Refresh tokens are not transmitted as often as the security keys used in the legacy API, so they are much less likely to be captured.

  • More efficient customization of messages across platforms For the message body, the HTTP v1 API has common keys that go to all targeted instances, plus platform-specific keys that let you customize the message across platforms. This allows you to create "overrides" that send slightly different payloads to different client platforms in a single message.

  • More extendable and future-proof for new client platform versions The HTTP v1 API fully supports messaging options available on iOS, Android and Web. Since each platform has its own defined block in the JSON payload, FCM can extend the API to new versions and new platforms as needed.

Any apps that use device group messaging or multicast messaging, however, may prefer to wait for future versions of the API. HTTP v1 does not support these features of the legacy API.

Update the server endpoint

The endpoint URL for the HTTP v1 API differs from the legacy endpont in these ways:

  • It is versioned, with /v1 in the path.
  • The path contains the project ID of the Firebase project for your app, in the format /projects/myproject-ID/. This ID is available in the General project settings tab of the Firebase console.
  • It explicitly specifies the specify the send method as :send.

To update the server endpoint for HTTP v1, add these elements to the endpoint in the header of your send requests.

Before

POST https://fcm.googleapis.com/fcm/send

After

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Update authorization of send requests

In place of the server key string used in legacy requests, HTTP v1 send requests require an OAuth 2.0 access token to be added to the header as Authorization: Bearer <valid Oauth 2.0 token>.

Before

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

After

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

Generate and retrieve the access token

Every Firebase project has a default service account. You can use this account to call Firebase server APIs from your app server or trusted environment. If you use a different service account, make sure it has Editor or Owner permissions.

To authenticate the service account and authorize it to access Firebase services, you must generate a private key file in JSON format and use this key to retrieve a short-lived OAuth 2.0 token. Once you have a valid token, you can add it in your server requests as required by the various Firebase services such as Remote Config or FCM.

To generate a private key file for your service account:

  1. In the Firebase console, open Settings > Service Accounts.
  2. Click Generate New Private Key, and confirm by clicking Generate Key.
  3. Securely store the JSON file containing the key. You'll need it to complete the next step.

To retrieve an access token:

To retrieve the token, you can use the Google API Client Library for your preferred language, referencing the private key JSON file as shown:

After your token expires, the token refresh method is called automatically to retrieve an updated token.

To authorize access to FCM, request the scope https://www.googleapis.com/auth/firebase.messaging.

To add the access token to an HTTP request header:

Add the token as the value of the Authorization header in the format Authorization: Bearer <access_token>:

node.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Update the payload of send requests

FCM HTTP v1 introduces a significant change in the structuring of the JSON message payload. Primarily, these changes ensure that messages are handled correctly when received on different client platforms; additionally, the changes give you extra flexibility to customize, or "override" message fields per platform.

In addition to inspecting the examples in this section, see Customizing a message across platforms and review the API reference to gain familiarity with HTTP v1.

Example: simple notification message

Here is a comparison of a very simple notification payload— containing title, body and data fields only— demonstrating the fundamental differences in legacy and HTTP v1 payloads.

Before

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

After

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Example: targeting multiple platforms

To enable multiple-platform targeting, the legacy API performed overrides in the backend. By contrast, HTTP v1 provides platform-specific blocks of keys that make any differences between platforms explicit and visible to the developer. This allows you to target multiple platforms always with a single request, as demonstrated in the following sample.

Before

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// iOS
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

After

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "aps": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Example: customizing with platform overrides

In addition to simplifying cross-platform targeting of messages, the HTTP v1 API provides flexibility to customize messages per platform.

Before

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// iOS
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

After

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

For more samples and information about the FCM HTTP v1 API, see the Firebase Blog.

Send feedback about...

Need help? Visit our support page.