You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用Cloud Function发送FCM通知时Token未定义问题求助

问题描述

在Flutter应用中,当用户添加单词时,需给关联伙伴发送新单词通知。Flutter端打印partnerFcmToken显示正常,但调用Cloud Function时始终返回“Token未定义”,Cloud Function日志提示“Partner FCM token is invalid or empty”,怀疑是请求参数传递方式有误,附上两端代码寻求解决。

Flutter端代码

String? partnerFcmToken = userSnap['partner_fcm_token'] as String?;

if (partnerFcmToken != null && partnerFcmToken.isNotEmpty) {
  print("Envoie notif fait.");
  print(partnerFcmToken);

  // Call the cloud function to send the notification
  final response = await FirebaseFunctions.instance
      .httpsCallable('sendNotificationToPartnerPhoneV2')
      .call({
     'token_partner': partnerFcmToken,
    'lang1': lang1, // Include lang1 in the request
    'lang2': lang2, // Include lang2 in the request
  });

  if (response.data['success']) {
    print("Notification sent successfully!");
  } else {
    print("Failed to send notification: ${response.data['error']}");
  }
}

Cloud Function端原代码

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

// eslint-disable-next-line max-len
exports.sendNotificationToPartnerPhoneV2 = functions.https.onCall(async (request) => {
  console.log("Starting sendNotificationToPartnerPhoneV2 function");

  // Retrieve the FCM token from the request
  const partnerFcmToken = request.token_partner;

  // Validate the FCM token
  if (typeof partnerFcmToken !== "string" || partnerFcmToken.trim() === "") {
    console.error("Invalid partner FCM token:", partnerFcmToken);
    return {success: false, error: "Partner FCM token is invalid or empty."};
  }

  // Prepare the notification message
  const message = {
    notification: {
      title: "Your partner added a new word!",
      // eslint-disable-next-line max-len
      body: `${request.lang1} / ${request.lang2}`, // Use template literals for message body
    },
    token: partnerFcmToken,
  };

  // Log the message to be sent
  console.log("Message to be sent:", JSON.stringify(message, null, 2));

  try {
    // Send the notification
    await admin.messaging().send(message);
    console.log("Notification sent successfully.");
    return {success: true};
  } catch (error) {
    console.error("Error sending notification:", error);
    return {success: false, error: error.message};
  }
});

解决方案

问题出在Cloud Function的参数处理逻辑:functions.https.onCall的函数签名与onRequest不同,它的第一个参数是客户端传递的数据对象,而非HTTP请求对象。原代码错误地将参数命名为request并直接取值,导致无法正确获取Flutter端传递的参数。

修正后的Cloud Function代码

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

exports.sendNotificationToPartnerPhoneV2 = functions.https.onCall(async (data, context) => {
  console.log("Starting sendNotificationToPartnerPhoneV2 function");

  // 从客户端传递的data对象中提取参数
  const partnerFcmToken = data.token_partner;
  const lang1 = data.lang1;
  const lang2 = data.lang2;

  // 验证FCM Token有效性
  if (typeof partnerFcmToken !== "string" || partnerFcmToken.trim() === "") {
    console.error("Invalid partner FCM token:", partnerFcmToken);
    return {success: false, error: "Partner FCM token is invalid or empty."};
  }

  // 构建通知消息
  const message = {
    notification: {
      title: "Your partner added a new word!",
      body: `${lang1} / ${lang2}`,
    },
    token: partnerFcmToken,
  };

  console.log("Message to be sent:", JSON.stringify(message, null, 2));

  try {
    await admin.messaging().send(message);
    console.log("Notification sent successfully.");
    return {success: true};
  } catch (error) {
    console.error("Error sending notification:", error);
    return {success: false, error: error.message};
  }
});

关键修正点

  • 将函数参数从(request)改为(data, context):data对应Flutter端call()方法传递的Map对象,context包含调用者的认证信息等上下文数据
  • 从data对象中获取token_partner、lang1、lang2参数,而非错误地从request中取值
  • 单独提取语言参数,提升代码可读性

内容的提问来源于stack exchange,提问作者Martin Guillon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:03:17