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

Vue.js集成Firebase手机号登录报错:TypeError: verifier.verify is not a function

Firebase Phone Auth 报错:TypeError: verifier.verify is not a function 解决方法

问题场景

首次在Vue.js中集成Firebase的signInWithPhoneNumber功能,reCAPTCHA能正常加载验证,但调用signInWithPhoneNumber时触发以下错误:

TypeError: verifier.verify is not a function
    at _verifyPhoneNumber (phone.ts?47a7:178:1)
    at signInWithPhoneNumber (phone.ts?47a7:106:1)
    at VueComponent.signIn (SignUp.vue?611a:68:1)
    at callback (SignUp.vue?611a:50:1)
    at eval (recaptcha_verifier.ts?c937:220:1)
    at lW.Y.lW.o (recaptcha__en.js:788:178)
    at M.R (recaptcha__en.js:437:30)
    at new Promise (<anonymous>)
    at lk.C (recaptcha__en.js:437:2)
    at Array.<anonymous> (recaptcha__en.js:415:375)

用户提供的代码如下:

模板代码

<template>
  <div>
    <h2>SignUp</h2>
    +60<input type="number" v-model="phNo" placeholder="Phone Number" />
    <button id="sign-in-button" @click="sendOtp">Get Recaptcha</button>
    <div id="recaptcha-container"></div>
    <br />
    <input type="number" v-model="otp" placeholder="OTP" />
    <button @click="verifyOtp">Verify</button><br />
    <button @click="sendOtp()">Resend OTP</button>
  </div>
</template>

脚本代码

<script>
import { initializeApp } from "@firebase/app";
import firebaseConfig from "@/firebaseConfig";

import {
  getAuth,
  signInWithPhoneNumber,
  RecaptchaVerifier,
} from "firebase/auth";

const app = initializeApp(firebaseConfig);
const auth = getAuth();

export default {
  name: "SignUp",
  data() {
    return {
      phNo: "",
      appVerifier: "",
      otp: "",
    };
  },
  methods: {
    sendOtp() {

      window.recaptchaVerifier = new RecaptchaVerifier(
        "recaptcha-container",
        {
          size: "normal",
          callback: (response) => {
            // reCAPTCHA solved, allow signInWithPhoneNumber.
            this.appVerifier = response;
            this.signIn(response);
          },
          "expired-callback": () => {
            // Response expired. Ask user to solve reCAPTCHA again.
          },
        },
        auth
      );
      recaptchaVerifier.render().then((widgetId) => {
        window.recaptchaWidgetId = widgetId;
      });
    },
    signIn(something) {
      console.log("running");

      let phoneNumber = "+60" + this.phNo;

      signInWithPhoneNumber(auth, phoneNumber, something)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          this.verifyOtp();
        })
        .catch((error) => {
          // Error; SMS not sent
          // ...
          console.log(error);
        });
    },
    //
    verifyOtp() {
      //
      console.log("running");
      let vm = this;
      let code = this.otp;
      window.confirmationResult
        .confirm(code)
        .then(function (result) {
          // User signed in successfully.
          var user = result.user;
          // ...
          //route to set password !
          vm.$router.push({ path: "/setPassword" });
        })
        .catch(function (error) {
          // User couldn't sign in (bad verification code?)
          // ...
        });
    },
  },
  created() {},
};
</script>

问题根源

核心错误是:signInWithPhoneNumber方法需要传入的是RecaptchaVerifier实例,但代码中错误地将reCAPTCHA回调返回的验证token传给了该方法,导致Firebase无法调用实例上的verify方法。

修复步骤

  1. 初始化RecaptchaVerifier时,将实例本身存入this.appVerifier,而非回调的response
  2. reCAPTCHA验证通过的回调中,直接调用this.signIn(),无需传递response参数
  3. 修正sendOtp中recaptchaVerifier.render()的引用(需加上window.前缀)
  4. 移除signIn方法的冗余参数,直接使用this.appVerifier作为signInWithPhoneNumber的第三个参数
  5. 移除signIn中自动调用this.verifyOtp()的逻辑,OTP验证需等待用户输入后手动触发

修复后的完整脚本代码

<script>
import { initializeApp } from "@firebase/app";
import firebaseConfig from "@/firebaseConfig";

import {
  getAuth,
  signInWithPhoneNumber,
  RecaptchaVerifier,
} from "firebase/auth";

const app = initializeApp(firebaseConfig);
const auth = getAuth();

export default {
  name: "SignUp",
  data() {
    return {
      phNo: "",
      appVerifier: null,
      otp: "",
    };
  },
  methods: {
    sendOtp() {
      // 初始化RecaptchaVerifier实例并保存
      this.appVerifier = new RecaptchaVerifier(
        "recaptcha-container",
        {
          size: "normal",
          callback: () => {
            // reCAPTCHA验证通过后触发发送OTP
            this.signIn();
          },
          "expired-callback": () => {
            // 处理验证过期逻辑
            alert("reCAPTCHA验证已过期,请重新验证");
          },
        },
        auth
      );
      // 渲染reCAPTCHA组件
      this.appVerifier.render().then((widgetId) => {
        window.recaptchaWidgetId = widgetId;
      });
    },
    signIn() {
      if (!this.phNo) {
        alert("请输入手机号码");
        return;
      }
      const phoneNumber = "+60" + this.phNo;
      // 使用保存的RecaptchaVerifier实例调用signInWithPhoneNumber
      signInWithPhoneNumber(auth, phoneNumber, this.appVerifier)
        .then((confirmationResult) => {
          // 保存确认结果,用于后续验证OTP
          window.confirmationResult = confirmationResult;
          alert("OTP已发送,请查收短信");
        })
        .catch((error) => {
          console.error("发送OTP失败:", error);
          // 重置reCAPTCHA
          if (window.recaptchaWidgetId) {
            this.appVerifier.reset(window.recaptchaWidgetId);
          }
        });
    },
    verifyOtp() {
      if (!this.otp || !window.confirmationResult) {
        alert("请先获取OTP并输入验证码");
        return;
      }
      const code = this.otp;
      window.confirmationResult
        .confirm(code)
        .then((result) => {
          const user = result.user;
          console.log("用户登录成功:", user);
          this.$router.push({ path: "/setPassword" });
        })
        .catch((error) => {
          console.error("OTP验证失败:", error);
          alert("验证码错误或已过期,请重新输入");
        });
    },
  },
};
</script>

模板说明

模板代码无需修改,保持原结构即可。

内容的提问来源于stack exchange,提问作者Abdullah Ibn Shahin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:00:54