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

Flutter调用Firebase HTTPS云函数时无法获取调用者UID的问题

问题根源

你当前使用的onRequest类型HTTPS云函数不会自动解析请求携带的Firebase Auth身份凭证,且如果直接将云函数HTTP地址生成二维码、扫码后通过系统浏览器打开请求,Flutter端的用户登录态根本不会被带入请求,自然无法获取触发用户的UID。

解决方案

你可以根据业务场景二选一:

方案1:改用onCall可调用云函数(推荐)

可调用云函数由Firebase SDK自动处理身份校验逻辑,不需要手动解析令牌,实现更简洁。

  • 云函数端代码修改如下:
exports.create = functions.https.onCall(async (data, context) => {
  // 校验用户登录状态
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', '用户未登录,无权操作');
  }
  // 直接从上下文获取触发用户UID
  const uid = context.auth.uid;
  // 写入数据库时可以关联UID
  const docRef = await admin.firestore().collection('games').add({
    points: 0,
    createdBy: uid,
    createTime: admin.firestore.FieldValue.serverTimestamp()
  });
  return {docId: docRef.id};
});
  • Flutter端适配:
    二维码内容不要存纯HTTP触发地址,改为存可调用函数的标识。用户扫码后不要跳转外部浏览器,直接在Flutter应用内通过官方云函数SDK调用:
// 引入cloud_functions依赖后调用
final callable = FirebaseFunctions.instance.httpsCallable('create');
final res = await callable();

调用时SDK会自动携带当前已登录用户的认证信息,云函数端可以直接读取到UID。

方案2:保留onRequest类型,手动校验身份令牌

如果你需要保留HTTP触发的形式,需要手动在请求中携带、校验用户ID令牌:

  • 云函数端代码修改如下:
exports.create = functions.https.onRequest(async (request, response) => {
  // 从请求头提取身份令牌
  const authHeader = request.headers.authorization;
  const idToken = authHeader?.startsWith('Bearer ') ? authHeader.split('Bearer ')[1] : null;
  if (!idToken) {
    return response.status(401).send('缺少身份凭证');
  }
  try {
    // 校验令牌合法性,解析用户信息
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    const uid = decodedToken.uid;
    await admin.firestore().collection('games').add({
      points: 0,
      createdBy: uid
    });
    return response.status(200).send('创建成功');
  } catch (err) {
    return response.status(401).send('身份凭证无效');
  }
});
  • Flutter端适配:
    用户扫码拿到云函数地址后,先获取当前登录用户的ID令牌,将令牌放入请求头后在应用内发起HTTP请求,不要跳转外部浏览器打开地址:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:http/http.dart' as http;

// 扫码后执行逻辑
final currentUser = FirebaseAuth.instance.currentUser;
if (currentUser == null) {
  // 处理未登录场景,比如跳登录页
  return;
}
final idToken = await currentUser.getIdToken();
final resp = await http.post(
  Uri.parse('扫码得到的云函数地址'),
  headers: {
    'Authorization': 'Bearer $idToken'
  }
);

核心注意点:无论用哪种方案,都不能让用户扫码后跳转到系统浏览器触发云函数,系统浏览器无法读取Flutter应用内的Firebase登录态,必然拿不到用户UID,所有请求逻辑必须在Flutter应用内部完成。

内容的提问来源于stack exchange,提问作者Usama Naufer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 22:09:21