Firebase cloud messaging HTTP v1 send error - 400 Client Error: Bad Request for url: https://fcm.googleapis.com/v1/projects/<PROJECT_ID>/messages:send
Firebase cloud messaging HTTP v1 send error - 400 Client Error: Bad Request for url: https://fcm.googleapis.com/v1/projects/<PROJECT_ID>/messages:send
我尝试使用 Firebase 云消息传递 HTTP v1
这是 运行 在 Windows
下的 Python 代码
import json
import requests
from google.oauth2.service_account import Credentials
import google.auth.transport.requests
def _get_access_token():
credentials = Credentials.from_service_account_file(
'C:/yocto/wenote-notification/send_notification/wenote-206215-firebase-adminsdk-9fpls-a3fdd2934c.json',
scopes=['https://www.googleapis.com/auth/firebase.messaging']
)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
access_token = credentials.token
return access_token
def generate_header():
return {'Authorization' : 'Bearer ' + _get_access_token(), 'Content-type' : 'application/json'}
# Header
headers = generate_header()
print(headers)
# Data
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": false, "sync_device_count": 2}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'
request_data = json.loads(string)
print(request_data)
r = requests.post('https://fcm.googleapis.com/v1/projects/wenote-206215/messages:send', headers=headers, json=request_data)
if r.status_code != 200:
r.raise_for_status()
我发送到 Firebase 服务器的消息是
{
"message":{
"token":"cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8",
"data":{
"sync":false,
"sync_device_count":2
},
"fcm_options":{
"analytics_label":"wenote_analytics_label"
}
}
}
但是,我收到以下错误
c:\yocto\wenote-notification\send_notification>python a.py
{'Authorization': 'Bearer ya29.c.Ko8BvQdCd-8US-DzQ-AcuTOURlGTQEvJt4mtofaeM08LRIhXBfC4RFN3QzkAcCdnaqI6uJLQlk1YJg67KQOhF8CtNux9t743nq2NN9uoW2mbQiB2y_2fjRUhiIIM7Wz2nt9rDOM4zFIFwKlHtLPXRLa4IGo0Ho-dq8zzVxQH1qPNGqy_ja8WowQCY5ReAQkmAmE', 'Content-type': 'application/json'}
{'message': {'token': 'cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8', 'data': {'sync': False, 'sync_device_count': 2}, 'fcm_options': {'analytics_label': 'wenote_analytics_label'}}}
Traceback (most recent call last):
File "a.py", line 38, in <module>
r.raise_for_status()
File "C:\Python36\lib\site-packages\requests\models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://fcm.googleapis.com/v1/projects/wenote-206215/messages:send
知道为什么会这样吗?我该如何解决?
我已经检查了我的 Firebase 云消息控制台。已启用。
您需要稍微调整 request_data 对象,因为架构已更改。
之前(旧版 http 协议):
{
"to": "/topics/news",
"notification": {
"title": "Breaking News",
"body": "New news story available."
},
"data": {
"story_id": "story_12345"
}
}
(HTTP v1 API)之后:
{
"message": {
"topic": "news",
"notification": {
"title": "Breaking News",
"body": "New news story available."
},
"data": {
"story_id": "story_12345"
}
}
}
注意主题参数的变化,以及消息对象的换行。
查看本指南:https://firebase.google.com/docs/cloud-messaging/migrate-v1
您可以查看这个基于 python 的非常简洁和结构化的 FCM 最小示例:https://github.com/firebase/quickstart-python/blob/688fcfa8068dcac67978a171df828c9e77cd320e/messaging/messaging.py#L57
这就是调试上述问题的方法。
使用
if r.status_code != 200:
print(r.text)
r.raise_for_status()
而不是
if r.status_code != 200:
r.raise_for_status()
我们会得到如下错误
{
"error": {
"code": 400,
"message": "Invalid value at 'message.data[0].value' (TYPE_STRING), false\nInvalid value at 'message.data[1].value' (TYPE_STRING), 2",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "message.data[0].value",
"description": "Invalid value at 'message.data[0].value' (TYPE_STRING), false"
},
{
"field": "message.data[1].value",
"description": "Invalid value at 'message.data[1].value' (TYPE_STRING), 2"
}
]
}
]
}
}
看起来 HTTP v1 对值类型非常严格(必须是字符串)
因此,而不是使用
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": false, "sync_device_count": 2}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'
我们需要使用
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": "false", "sync_device_count": "2"}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'
我尝试使用 Firebase 云消息传递 HTTP v1
这是 运行 在 Windows
下的 Python 代码import json
import requests
from google.oauth2.service_account import Credentials
import google.auth.transport.requests
def _get_access_token():
credentials = Credentials.from_service_account_file(
'C:/yocto/wenote-notification/send_notification/wenote-206215-firebase-adminsdk-9fpls-a3fdd2934c.json',
scopes=['https://www.googleapis.com/auth/firebase.messaging']
)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
access_token = credentials.token
return access_token
def generate_header():
return {'Authorization' : 'Bearer ' + _get_access_token(), 'Content-type' : 'application/json'}
# Header
headers = generate_header()
print(headers)
# Data
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": false, "sync_device_count": 2}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'
request_data = json.loads(string)
print(request_data)
r = requests.post('https://fcm.googleapis.com/v1/projects/wenote-206215/messages:send', headers=headers, json=request_data)
if r.status_code != 200:
r.raise_for_status()
我发送到 Firebase 服务器的消息是
{
"message":{
"token":"cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8",
"data":{
"sync":false,
"sync_device_count":2
},
"fcm_options":{
"analytics_label":"wenote_analytics_label"
}
}
}
但是,我收到以下错误
c:\yocto\wenote-notification\send_notification>python a.py
{'Authorization': 'Bearer ya29.c.Ko8BvQdCd-8US-DzQ-AcuTOURlGTQEvJt4mtofaeM08LRIhXBfC4RFN3QzkAcCdnaqI6uJLQlk1YJg67KQOhF8CtNux9t743nq2NN9uoW2mbQiB2y_2fjRUhiIIM7Wz2nt9rDOM4zFIFwKlHtLPXRLa4IGo0Ho-dq8zzVxQH1qPNGqy_ja8WowQCY5ReAQkmAmE', 'Content-type': 'application/json'}
{'message': {'token': 'cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8', 'data': {'sync': False, 'sync_device_count': 2}, 'fcm_options': {'analytics_label': 'wenote_analytics_label'}}}
Traceback (most recent call last):
File "a.py", line 38, in <module>
r.raise_for_status()
File "C:\Python36\lib\site-packages\requests\models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://fcm.googleapis.com/v1/projects/wenote-206215/messages:send
知道为什么会这样吗?我该如何解决?
我已经检查了我的 Firebase 云消息控制台。已启用。
您需要稍微调整 request_data 对象,因为架构已更改。
之前(旧版 http 协议):
{
"to": "/topics/news",
"notification": {
"title": "Breaking News",
"body": "New news story available."
},
"data": {
"story_id": "story_12345"
}
}
(HTTP v1 API)之后:
{
"message": {
"topic": "news",
"notification": {
"title": "Breaking News",
"body": "New news story available."
},
"data": {
"story_id": "story_12345"
}
}
}
注意主题参数的变化,以及消息对象的换行。
查看本指南:https://firebase.google.com/docs/cloud-messaging/migrate-v1
您可以查看这个基于 python 的非常简洁和结构化的 FCM 最小示例:https://github.com/firebase/quickstart-python/blob/688fcfa8068dcac67978a171df828c9e77cd320e/messaging/messaging.py#L57
这就是调试上述问题的方法。
使用
if r.status_code != 200:
print(r.text)
r.raise_for_status()
而不是
if r.status_code != 200:
r.raise_for_status()
我们会得到如下错误
{
"error": {
"code": 400,
"message": "Invalid value at 'message.data[0].value' (TYPE_STRING), false\nInvalid value at 'message.data[1].value' (TYPE_STRING), 2",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "message.data[0].value",
"description": "Invalid value at 'message.data[0].value' (TYPE_STRING), false"
},
{
"field": "message.data[1].value",
"description": "Invalid value at 'message.data[1].value' (TYPE_STRING), 2"
}
]
}
]
}
}
看起来 HTTP v1 对值类型非常严格(必须是字符串)
因此,而不是使用
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": false, "sync_device_count": 2}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'
我们需要使用
string = '{"message":{"token": "cSW75-6OF-w:APA91bE-E6vWucBe8rRijpDLlZGHhyfwoaLJr3R1TZEvieBM-__ZXwXlBS34kUticUN_eSbwvQGTymbmtd7sHT5U9O_v9HePyVn7jnUD9IBdoZZYSQ1CrgxXS1sz9wjAd5pKHIddoKj8", "data": {"sync": "false", "sync_device_count": "2"}, "fcm_options": {"analytics_label": "wenote_analytics_label"}}}'