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

FirebaseUser.updatePhoneNumber方法中PhoneAuthCredential参数使用疑问

解决Firebase用户手机号更新:PhoneAuthCredential的正确使用方式

嘿,我完全懂你现在的处境——明明知道FirebaseUser.updatePhoneNumber()是更新官方用户表手机号的正确方法,但对着PhoneAuthCredential的复杂构造函数完全摸不着头脑,搜了半天也没找到靠谱的示例对吧?别慌,这其实是因为Firebase不推荐直接用构造函数创建这个凭证,咱们用官方提供的静态方法就简单多了,我给你一步步拆解怎么做。

核心逻辑:通过验证码获取PhoneAuthCredential

更新Firebase用户的手机号属于敏感操作,必须先验证新手机号的所有权,所以流程是:

  1. 向用户要新手机号,发送验证码到该号码
  2. 用户输入验证码后,用验证码和验证ID生成PhoneAuthCredential
  3. 调用updatePhoneNumber()完成更新

步骤1:发送验证码到新手机号

首先,你需要调用Firebase的手机号验证API,给用户输入的新手机号发送验证码:

Kotlin 示例

import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.PhoneAuthOptions
import com.google.firebase.auth.PhoneAuthProvider
import java.util.concurrent.TimeUnit

// 保存验证ID和重发令牌(用于后续重发验证码)
private var verificationId: String? = null
private var resendToken: PhoneAuthProvider.ForceResendingToken? = null

fun sendVerificationCode(newPhoneNumber: String) {
    val options = PhoneAuthOptions.newBuilder(FirebaseAuth.getInstance())
        .setPhoneNumber(newPhoneNumber) // 用户输入的新手机号
        .setTimeout(60L, TimeUnit.SECONDS) // 验证码过期时间
        .setActivity(this) // 当前Activity(用于自动验证场景)
        .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                // 自动验证成功(比如设备是测试机或运营商自动转发),直接用这个凭证更新手机号
                updateUserPhoneNumber(credential)
            }

            override fun onVerificationFailed(e: Exception) {
                // 验证失败,比如手机号格式错误、网络问题
                Log.e("PhoneUpdate", "验证码发送失败:${e.message}")
            }

            override fun onCodeSent(id: String, token: PhoneAuthProvider.ForceResendingToken) {
                // 验证码发送成功,保存验证ID和重发令牌
                verificationId = id
                resendToken = token
                // 这里可以跳转到验证码输入界面,让用户输入收到的验证码
            }
        })
        .build()
    PhoneAuthProvider.verifyPhoneNumber(options)
}

Java 示例

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.PhoneAuthOptions;
import com.google.firebase.auth.PhoneAuthProvider;
import java.util.concurrent.TimeUnit;

private String verificationId;
private PhoneAuthProvider.ForceResendingToken resendToken;

public void sendVerificationCode(String newPhoneNumber) {
    PhoneAuthOptions options = PhoneAuthOptions.newBuilder(FirebaseAuth.getInstance())
            .setPhoneNumber(newPhoneNumber)
            .setTimeout(60L, TimeUnit.SECONDS)
            .setActivity(this)
            .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
                @Override
                public void onVerificationCompleted(PhoneAuthCredential credential) {
                    updateUserPhoneNumber(credential);
                }

                @Override
                public void onVerificationFailed(Exception e) {
                    Log.e("PhoneUpdate", "验证码发送失败:" + e.getMessage());
                }

                @Override
                public void onCodeSent(String id, PhoneAuthProvider.ForceResendingToken token) {
                    verificationId = id;
                    resendToken = token;
                }
            })
            .build();
    PhoneAuthProvider.verifyPhoneNumber(options);
}

步骤2:用验证码生成PhoneAuthCredential并更新手机号

当用户输入验证码后,用之前保存的verificationId和用户输入的验证码生成凭证,然后调用更新方法:

Kotlin 示例

fun verifyCodeAndUpdatePhone(smsCode: String) {
    verificationId?.let { id ->
        val credential = PhoneAuthProvider.getCredential(id, smsCode)
        updateUserPhoneNumber(credential)
    } ?: run {
        Log.e("PhoneUpdate", "验证ID为空,请先发送验证码")
    }
}

private fun updateUserPhoneNumber(credential: PhoneAuthCredential) {
    val currentUser = FirebaseAuth.getInstance().currentUser
    currentUser?.updatePhoneNumber(credential)
        ?.addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // 手机号更新成功,同步更新你的自定义users节点
                Log.d("PhoneUpdate", "用户手机号更新成功")
                val newPhone = currentUser.phoneNumber
                updateCustomUsersNode(newPhone) // 这里调用你更新自定义节点的代码
            } else {
                // 更新失败,处理不同的错误场景
                when (val exception = task.exception) {
                    is FirebaseAuthInvalidCredentialsException -> {
                        Log.e("PhoneUpdate", "验证码无效或已过期")
                    }
                    is FirebaseAuthRecentLoginRequiredException -> {
                        Log.e("PhoneUpdate", "需要重新登录,请先验证用户身份")
                        // 这里可以提示用户重新登录,比如用原手机号/密码登录后再尝试更新
                    }
                    else -> {
                        Log.e("PhoneUpdate", "更新失败:${exception?.message}")
                    }
                }
            }
        }
}

Java 示例

public void verifyCodeAndUpdatePhone(String smsCode) {
    if (verificationId != null) {
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, smsCode);
        updateUserPhoneNumber(credential);
    } else {
        Log.e("PhoneUpdate", "验证ID为空,请先发送验证码");
    }
}

private void updateUserPhoneNumber(PhoneAuthCredential credential) {
    FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
    if (currentUser != null) {
        currentUser.updatePhoneNumber(credential)
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        Log.d("PhoneUpdate", "用户手机号更新成功");
                        String newPhone = currentUser.getPhoneNumber();
                        updateCustomUsersNode(newPhone); // 同步更新自定义节点
                    } else {
                        Exception exception = task.getException();
                        if (exception instanceof FirebaseAuthInvalidCredentialsException) {
                            Log.e("PhoneUpdate", "验证码无效或已过期");
                        } else if (exception instanceof FirebaseAuthRecentLoginRequiredException) {
                            Log.e("PhoneUpdate", "需要重新登录,请先验证用户身份");
                        } else {
                            Log.e("PhoneUpdate", "更新失败:" + exception.getMessage());
                        }
                    }
                });
    }
}

关键注意事项

  • 不要直接使用构造函数:你看到的PhoneAuthCredential的复杂构造函数是Firebase内部使用的,官方推荐用PhoneAuthProvider.getCredential()静态方法来创建实例,这才是标准用法。
  • 敏感操作需重新验证:如果用户登录时间较长,Firebase会抛出FirebaseAuthRecentLoginRequiredException,这时候需要让用户重新登录(比如用原手机号或密码),再执行更新操作。
  • 同步自定义节点:在官方用户表更新成功后,一定要记得同步更新你自己的users节点,确保两处数据一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:13