由使用旧版 HTTP 改为使用 HTTP v1

如果应用使用的是 FCM 旧版 HTTP API,您应该考虑按照本指南中的说明改为使用 HTTP v1 API。与旧版 API 相比,HTTP v1 API 具有以下优势:

  • 可通过访问令牌提供更好的安全性:HTTP v1 API 会根据 OAuth2 安全模型使用只在短时间内有效的访问令牌。即使访问令牌变成公开状态,能被恶意使用的时间也只有 1 小时,之后令牌就会失效。传输刷新令牌的频率不像传输旧版 API 中使用的安全密钥那样频繁,因此这些令牌被捕获的可能性要低得多。

  • 可针对不同平台更高效地自定义消息:在消息正文中,HTTP v1 API 加入了会传输到所有已定位实例的通用键,以及针对具体平台的键(方便您针对不同平台自定义消息)。这样,您就可以创建“替换项”,这些替换项可在一则消息中向不同的客户端平台发送略有不同的有效负载。

  • 对于新的客户端平台版本,扩展性和适应性更出色:HTTP v1 API 完全支持 iOS、Android 和网页支持的消息传递选项。由于 JSONN 有效负载中包含每个平台自己的定义块,因此 FCM 可以根据需要扩展 API 以支持新版本及新平台。

不过,使用设备组消息传递或多播消息传递的应用可能更倾向于等待使用未来版本的 API。HTTP v1 不支持旧版 API 的这些功能。

更新服务器端点

HTTP v1 API 的端点网址与旧版端点的不同之处表现在以下几个方面:

  • 带版本号,并且路径中包含 /v1
  • 路径中包含您应用的 Firebase 项目的项目 ID(格式为 /projects/myproject-ID/)。您可以在 Firebase 控制台的常规项目设置标签中找到此 ID。
  • 它明确将 send 方法指定为 :send

要更新 HTTP v1 的服务器端点,请在发送请求的标头中向端点中添加这些元素。

以前

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

此后

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

更新发送请求的授权

HTTP v1 发送请求需要将 OAuth 2.0 访问令牌以 Authorization: Bearer <valid Oauth 2.0 token> 的形式添加到标头中,以替换旧版请求中使用的服务器密钥字符串。

以前

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

此后

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

生成和检索访问令牌

每个 Firebase 项目都有一个默认的服务帐号。您可以使用此帐号从您的应用服务器或受信任环境调用 Firebase 服务器 API。如果您要使用其他服务帐号,请确保帐号拥有修改者或所有者权限。

要对服务帐号进行身份验证并授权其访问 Firebase 服务,您必须生成 JSON 格式的私钥文件,并使用此密钥来检索在短时间内有效的 OAuth 2.0 令牌。获得有效令牌后,您可以根据各种 Firebase 服务(如远程配置或 FCM)的要求将其添加到服务器请求中。

要为您的服务帐号生成私钥文件,请执行以下操作:

  1. 在 Firebase 控制台中,打开设置 > 服务帐号
  2. 点击生成新的私钥,然后点击生成密钥进行确认。
  3. 妥善存储包含密钥的 JSON 文件。您将需要此文件才能完成下一步操作。

检索访问令牌:

要检索令牌,您可以使用与您偏好的编程语言对应的 Google API 客户端库,并按如下所示引用私钥 JSON 文件:

在您的令牌过期后,系统会自动调用令牌刷新方法以检索更新的令牌。

要授予访问 FCM 的权限,应请求范围 https://www.googleapis.com/auth/firebase.messaging

将访问令牌添加到 HTTP 请求标头中:

Authorization: Bearer <access_token> 格式将令牌添加为 Authorization 标头的值:

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;

更新发送请求的有效负载

FCM HTTP v1 使 JSON 消息有效负载的结构发生了极大的变化。首先,这些变化可确保不同的客户端平台在收到消息后会正确处理这些消息;此外,这些变化还能让您更加灵活地为每个平台自定义或“替换”消息字段。

除了查看本部分中的示例外,您还可以参阅针对不同平台自定义消息和查看 API 参考,以熟悉 HTTP v1。

示例:简单的通知消息

下文通过一个非常简单的通知有效负载(仅包含 titlebodydata 字段)进行了对比,展示了旧版有效负载与 HTTP v1 有效负载之间的基本差异。

以前

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

此后

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

示例:定位多个平台

旧版 API 通过在后端执行替换来实现多平台定位。相比之下,HTTP v1 则提供针对具体平台的键块,让开发者对平台之间的任何差异一目了然。这样可让您始终通过一个请求定位多个平台,如以下示例所示。

以前

// 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"
  }
}

此后

{
  "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"
        }
      }
    }
  }
}

示例:通过平台替换项进行自定义

除了简化了消息的跨平台定位外,HTTP v1 API 还可让您灵活地为每个平台自定义消息。

以前

// 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"
  }
}

此后

{
  "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"
        }
      }
    }
  }
}

如需查看更多示例并详细了解 FCM HTTP v1 API,请参阅 Firebase 博客

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面