Firebase Functions中admin.firestore.Timestamp.fromDate未定义报错求助
解决Firebase Functions中OTP过期时间设置的"Cannot read properties of undefined (reading 'fromDate')"错误
问题原因
你遇到的错误是因为Firebase Admin SDK v9+版本中,Timestamp不再挂载在admin.firestore对象下,而是需要从firebase-admin/firestore模块单独导入。你代码中注释了Timestamp的导入语句,导致尝试访问admin.firestore.Timestamp时返回undefined,进而调用fromDate方法时触发报错。
解决方案
- 取消注释
Timestamp的导入语句 - 将代码中所有
admin.firestore.Timestamp替换为导入的Timestamp对象
修改后的完整代码
import * as functions from "firebase-functions"; import * as admin from "firebase-admin"; import twilio from "twilio"; import * as dotenv from "dotenv"; import { Timestamp } from "firebase-admin/firestore"; // 启用Timestamp的单独导入 dotenv.config(); admin.initializeApp(); const twilioClient = twilio( process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN ); const generateOtp = (): string => { return Math.floor(100000 + Math.random() * 900000).toString(); }; // Send OTP via SMS export const sendOtpSms = functions.https.onRequest(async (req, res) => { const {phoneNumber} = req.body; if (!phoneNumber) { res.status(400).json({error: "Phone number is required"}); return; } const otp = generateOtp(); try { await twilioClient.messages.create({ body: `Your OTP is ${otp}`, from: process.env.TWILIO_PHONE, to: phoneNumber, }); // 使用导入的Timestamp创建过期时间 const expiresAt = Timestamp.fromDate( new Date(Date.now() + 5 * 60000) ); await admin.firestore().collection("otps").doc(phoneNumber).set({ otp, expiresAt, }); console.log(`Generated OTP: ${otp}, Expires At: ${expiresAt.toDate()}`); res.status(200).json({message: "OTP sent successfully"}); } catch (error) { console.error("Error sending OTP:", error); res.status(500).json({error: "Failed to send OTP"}); } }); // Verify Otp export const verifyOtp = functions.https.onRequest(async (req, res) => { const {phoneNumber, otp} = req.body; if (!phoneNumber || !otp) { res.status(400).json({error: "Phone number and OTP are required"}); return; } try { const otpDoc = await admin .firestore() .collection("otps") .doc(phoneNumber) .get(); if (!otpDoc.exists) { res.status(404).json({error: "OTP not found"}); return; } const otpData = otpDoc.data(); if (!otpData || !otpData.expiresAt) { res.status(400).json({error: "OTP data is incomplete"}); return; } // 从Firestore读取的expiresAt本身是Timestamp类型,可直接调用toDate() const isExpired = otpData.expiresAt.toDate() < new Date(); if (isExpired) { res.status(400).json({error: "OTP has expired"}); return; } if (otp !== otpData.otp) { res.status(400).json({error: "Invalid OTP"}); return; } res.status(200).json({message: "OTP verified successfully"}); } catch (error) { console.error("Error verifying OTP:", error); res.status(500).json({error: "Failed to verify OTP"}); } });
额外优化建议
- 移除原代码中判断
admin.firestore.Timestamp.fromDate是否存在的冗余逻辑,导入正确的Timestamp后该方法必然可用 - 验证OTP成功后,建议删除对应的OTP文档,避免被重复使用
- 确认
package.json中firebase-admin依赖为最新稳定版,避免版本兼容问题
内容的提问来源于stack exchange,提问作者Abiodun Bankole
相关产品推荐
相关产品推荐

