Server: FCM HTTP v1 target in fid instead of deprecated token (D-083 follow-up)

The stored fcm_token is the Firebase Installation ID; HTTP v1 deprecates
message.token (accepted only during the transition) in favour of message.fid.
Push examples and push_fcm tests follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-18 15:16:09 +02:00
parent a3127586ca
commit f56dcbe5f7
10 changed files with 15 additions and 12 deletions
+3 -1
View File
@@ -113,10 +113,12 @@ pub fn entity_type_of(push_type: PushType) -> &'static str {
}
/// The HTTP v1 request body for one device (SPEC §14.6): data only, every value a string, ids only (AC-13.8).
/// The target is `fid`: the stored `fcm_token` is the Firebase Installation ID the phone registered (D-083), and
/// HTTP v1 deprecates `token` in favour of `fid` (D-096).
pub fn message_body(fcm_token: &str, message: &PushMessage) -> Value {
json!({
"message": {
"token": fcm_token,
"fid": fcm_token,
"android": { "priority": "high", "ttl": MESSAGE_TTL },
"data": {
"v": PAYLOAD_VERSION,
@@ -117,7 +117,7 @@ fn payload_of_every_type_equals_the_contract_example() {
actor_user_id: data["actor_user_id"].as_str().unwrap().parse().unwrap(),
count: data["count"].as_str().unwrap().parse().unwrap(),
};
let body = message_body(expected["message"]["token"].as_str().unwrap(), &msg);
let body = message_body(expected["message"]["fid"].as_str().unwrap(), &msg);
assert_eq!(body, expected, "{}", push_type.as_str());
// Data only, every value a string (SPEC §14.6), ids only (AC-13.8).
assert!(body["message"].get("notification").is_none());
@@ -178,7 +178,7 @@ async fn oauth_jwt_and_send_request_follow_the_http_v1_flow() {
sends[0].authorization.as_deref(),
Some("Bearer ya29.stub-1")
);
let expected = json!({"message": {"token": "tok-member", "android": {"priority": "high", "ttl": "86400s"},
let expected = json!({"message": {"fid": "tok-member", "android": {"priority": "high", "ttl": "86400s"},
"data": {"v": "1", "type": "expense_created", "entity_type": "expense", "entity_id": EXPENSE,
"actor_user_id": ADMIN_ID, "count": "1"}}});
assert_eq!(sends[0].json(), expected);
@@ -460,7 +460,8 @@ async fn sync_push_reaches_fcm_through_the_queue_and_the_sender_task() {
let sends = s.stub.sends();
assert_eq!(sends.len(), 1);
let body = sends[0].json();
assert_eq!(body["message"]["token"], "tok-admin");
assert_eq!(body["message"]["fid"], "tok-admin");
assert!(body["message"].get("token").is_none());
assert_eq!(body["message"]["data"]["entity_id"], id);
assert_eq!(body["message"]["data"]["actor_user_id"], MEMBER_ID);
}