Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

從舊版HTTP遷移到HTTP v1

使用FCM舊版HTTP API的應用應考慮按照本指南中的說明遷移到HTTP v1 API。與舊版API相比,HTTP v1 API具有以下優勢:

  • 通過訪問令牌提供更好的安全性 HTTP v1 API根據OAuth2安全模型使用短期訪問令牌。如果訪問令牌公開,則在過期之前只能被惡意使用一個小時左右。刷新令牌的傳輸頻率不如舊版API中使用的安全密鑰,因此捕獲令牌的可能性大大降低。

  • 跨平台更有效地定制消息對於消息主體,HTTP v1 API具有可用於所有目標實例的通用密鑰,以及使您可以跨平台定制消息的特定於平台的密鑰。這使您可以創建“替代”,從而在一條消息中將略有不同的有效負載發送到不同的客戶端平台。

  • 新客戶端平台版本具有更強的可擴展性和麵向未來的功能HTTP v1 API完全支持iOS,Android和Web上可用的消息傳遞選項。由於每個平台在JSON有效負載中都有自己定義的塊,因此FCM可以根據需要將API擴展到新版本和新平台。

更新服務器端點

HTTP v1 API的端點URL在以下方面與舊式端點有所不同:

  • 已對其進行版本控制,路徑中帶有/v1
  • 路徑包含您的應用程序的Firebase項目的項目ID,格式為/projects/myproject-ID/ 。該ID在Firebase控制台的“ 常規項目設置”選項卡中可用。
  • 它顯式指定將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訪問令牌。如果您使用Admin SDK發送消息,則庫將為您處理令牌。如果您使用的是原始協議,請按照本節中的說明獲取令牌,並將其作為Authorization: Bearer <valid Oauth 2.0 token>添加到標頭中。

之前

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

 Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
 

根據您服務器環境的詳細信息,使用以下策略的組合來授權服務器對Firebase服務的請求:

  • Google應用程序默認憑據(ADC)
  • 服務帳戶JSON文件
  • 從服務帳戶派生的短期OAuth 2.0訪問令牌

如果您的應用程序在Compute Engine,Kubernetes Engine,App Engine或云功能 (包括Firebase的雲功能)上運行,請使用應用程序默認憑據(ADC)。 ADC使用您現有的默認服務帳戶來獲取用於授權請求的憑據,並且ADC通過環境變量GOOGLE_APPLICATION_CREDENTIALS啟用靈活的本地測試。為了實現授權流程的最大程度的自動化,請將ADC與Admin SDK服務器庫一起使用。

如果您的應用程序在非Google服務器環境上運行 ,則需要從Firebase項目下載服務帳戶JSON文件。只要您有權訪問包含私鑰文件的文件系統,就可以使用環境變量GOOGLE_APPLICATION_CREDENTIALS來授權使用這些手動獲得的憑據進行的請求。如果沒有這種文件訪問權限,則必須在代碼中引用服務帳戶文件-由於存在暴露憑據的風險,因此應格外小心。

使用ADC提供憑據

Google應用程序默認憑據(ADC)按以下順序檢查您的憑據:

  1. ADC檢查是否設置了環境變量GOOGLE_APPLICATION_CREDENTIALS 。如果設置了變量,則ADC使用變量指向的服務帳戶文件。

  2. 如果未設置環境變量,則ADC使用Compute Engine,Kubernetes Engine,App Engine和Cloud Functions為在這些服務上運行的應用程序提供的默認服務帳戶。

  3. 如果ADC無法使用以上任何一個憑據,則係統將引發錯誤。

以下Admin SDK代碼示例說明了此策略。該示例未明確指定應用程序憑據。但是,只要設置了環境變量,或者只要應用程序在Compute Engine,Kubernetes Engine,App Engine或Cloud Functions上運行,ADC都可以隱式找到憑據。

Node.js

 admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});
 

爪哇

 FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);
 

蟒蛇

 default_app = firebase_admin.initialize_app()
 

 app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
} 

C#

 FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});
 

手動提供憑證

Firebase項目支持Google 服務帳戶 ,您可以使用這些帳戶從您的應用服務器或受信任的環境中調用Firebase服務器API。如果要在本地開發代碼或在本地部署應用程序,則可以使用通過此服務帳戶獲得的憑據來授權服務器請求。

要驗證服務帳戶並授權其訪問Firebase服務,您必須生成JSON格式的私鑰文件。

為您的服務帳戶生成私鑰文件:

  1. 在Firebase控制台中,打開“設置”>“ 服務帳戶”

  2. 單擊生成新私鑰 ,然後單擊生成密鑰進行確認。

  3. 安全地存儲包含密鑰的JSON文件。

通過服務帳戶進行授權時,有兩種選擇可為您的應用程序提供憑據。您可以設置GOOGLE_APPLICATION_CREDENTIALS環境變量,也可以將路徑明確傳遞給代碼中的服務帳戶密鑰。第一個選項更安全,強烈建議使用。

設置環境變量:

將環境變量GOOGLE_APPLICATION_CREDENTIALS設置為包含您的服務帳戶密鑰的JSON文件的文件路徑。該變量僅適用於當前的Shell會話,因此,如果您打開一個新的會話,請再次設置該變量。

Linux或macOS

 export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
 

視窗

使用PowerShell:

 $env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
 

完成上述步驟後,應用程序默認憑據(ADC)可以隱式確定您的憑據,從而允許您在非Google環境中測試或運行時使用服務帳戶憑據。

使用憑證創建訪問令牌

將您的Firebase憑據與Google API客戶端庫一起用於您的首選語言,以檢索短暫的OAuth 2.0訪問令牌:

node.js

  function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
} 

在此示例中,Google API客戶端庫使用JSON網絡令牌或JWT對請求進行身份驗證。有關更多信息,請參閱JSON Web令牌

蟒蛇

 def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token 

爪哇

 private static String getAccessToken() throws IOException {
  GoogleCredential googleCredential = GoogleCredential
      .fromStream(new FileInputStream("service-account.json"))
      .createScoped(Arrays.asList(SCOPES));
  googleCredential.refreshToken();
  return googleCredential.getAccessToken();
} 

訪問令牌過期後,將自動調用令牌刷新方法以檢索更新的訪問令牌。

要授權對FCM的訪問,請請求範圍https://www.googleapis.com/auth/firebase.messaging

要將訪問令牌添加到HTTP請求標頭中:

將令牌作為Authorization標頭的值添加,格式為Authorization: Bearer <access_token>

node.js

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

蟒蛇

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

爪哇

 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博客