Получаю ошибку:
"Ошибка отправки кода подтверждения: FirebaseError: Firebase: Ошибка (auth/invalid-) app-credential)"
Конфигурации моего приложения соответствуют настройкам в консоли, и аутентификация работает с номером телефона, указанным в разделе тестирования, но не удается отправить сообщение на мой личный номер.
Номер имеет правильный формат: +код страны+номер(+92334*******), а мой план оплаты — Blaze (оплата по мере использования).
код
Firebase.ts:
Код: Выделить всё
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
.......
};
// Initialize Firebase App
const app = initializeApp(firebaseConfig);
// Export Firebase Auth instance
export const auth = getAuth(app);
Код: Выделить всё
import { RecaptchaVerifier, signInWithPhoneNumber, PhoneAuthProvider, signInWithCredential } from "firebase/auth";
import { auth } from "../app/firebase/firebaseConfig";
export const initializeRecaptcha = () => {
if (!window.recaptchaVerifier) {
window.recaptchaVerifier = new RecaptchaVerifier(
auth,
"recaptcha-container",
{
size: "normal", // Use 'invisible' for a hidden reCAPTCHA
callback: (response: any) => {
console.log("reCAPTCHA solved:", response);
},
"expired-callback": () => {
console.error("reCAPTCHA expired. Please try again.");
},
}
);
}
return window.recaptchaVerifier;
};
export const sendCode = async (phoneNumber: string) => {
debugger
if (!window.recaptchaVerifier) initializeRecaptcha();
try {
if (!window.recaptchaVerifier) {
throw new Error("ReCAPTCHA verifier not initialized");
}
const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, window.recaptchaVerifier!);
//.then((confirmationResult) => {
// debugger
// window.confirmationResult = confirmationResult;
// Toast.show("success", "OTP sent successfully");
//})
//.catch((error) => {
// debugger
// console.log(error);
//});
return confirmationResult;
} catch (error) {
console.error("Error sending verification code:", error);
throw error;
}
};
export const verifyCode = async (verificationId: string, verificationCode: string) => {
const credential = PhoneAuthProvider.credential(verificationId, verificationCode);
return await signInWithCredential(auth, credential);
};
Код: Выделить всё
import { useEffect, useRef, useState } from "react";
import { Formik, ErrorMessage } from "formik";
import { Button, Form, Header, Label, Segment } from "semantic-ui-react";
import * as Yup from "yup";
import MyTextInput from "../../app/common/form/MyTextInput";
import Toast from "../../utils/Toast";
import { initializeRecaptcha, sendCode, /*validateRecaptchaToken,*/ verifyCode } from "../../utils/firebaseUtils";
interface Props {
email?: string; // Optional: for email verification
phoneNumber?: string; // Optional: for phone number verification
onSuccess?: () => void; // Callback after successful verification
}
export default function VerifyToken({ email, phoneNumber, onSuccess }: Props) {
const [timer, setTimer] = useState(120); // 2-minute countdown timer
const [isTimerActive, setIsTimerActive] = useState(false);
const [verificationId, setVerificationId] = useState(null);
const hasRun = useRef(false);
useEffect(() => {
if (phoneNumber && !hasRun.current) {
handleCodeRequest();
hasRun.current = true;
}
}, [phoneNumber]);
useEffect(() => {
let countdown: NodeJS.Timeout;
if (isTimerActive && timer > 0) {
countdown = setInterval(() => setTimer((prev) => prev - 1), 1000);
} else if (timer clearInterval(countdown);
}, [isTimerActive, timer]);
const handleCodeRequest = async () => {
if (email) {
Toast.show("info", `A code has been sent to your email: ${maskEmail(email)}`);
} else if (phoneNumber) {
try {
debugger
// Initialize reCAPTCHA
const recaptchaVerifier = initializeRecaptcha();
// Wait for reCAPTCHA to be solved
const recaptchaToken = await recaptchaVerifier.verify();
//await validateRecaptchaToken(recaptchaToken)
console.log("reCAPTCHA solved, token:", recaptchaToken);
debugger
// Send the verification code after solving reCAPTCHA
const result = await sendCode(phoneNumber);
if (result) {
setVerificationId(result.verificationId);
Toast.show("info", `A verification code was sent to ${phoneNumber}.`);
setIsTimerActive(true);
}
} catch (error) {
console.error("Error sending verification code:", error);
Toast.show("error", "Failed to send verification code. Please try again.");
}
}
};
const handleSubmit = async (code: string, setErrors: (errors: { error: string }) => void) => {
if (email) {
Toast.show("success", "Email verification successful!");
onSuccess && onSuccess();
return;
}
if (!verificationId) {
setErrors({ error: "Verification ID not available. Please resend the code." });
return;
}
try {
const userCredential = await verifyCode(verificationId, code);
if (userCredential) {
Toast.show("success", "Phone number verified successfully!");
onSuccess && onSuccess();
} else {
throw new Error("Verification failed.");
}
} catch (error: any) {
console.error("Verification error:", error.message);
setErrors({ error: "Invalid code. Please try again or resend." });
}
};
const formatTime = () => {
const minutes = Math.floor(timer / 60);
const seconds = timer % 60;
return `${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
};
const maskEmail = (email: string | null) => {
if (!email) return "";
const [localPart, domain] = email.split("@");
if (localPart.length setErrors({ error: error.message }))}
>
{({ handleSubmit, errors, isValid, isSubmitting }) => (
} />
{isTimerActive ? Try again in {formatTime()} : Resend Code}
)}
);
}
URL-адрес запроса:
https://identitytoolkit.googleapis.com/ ... de?key=key
Запрос Метод:
POST
Код состояния:
400 Неверный запрос
Удаленный адрес:
адрес
Политика реферера:
без реферера
полезная нагрузка:
{
"phoneNumber": "+9231********",
"clientType ": "CLIENT_TYPE_WEB",
"captchaResponse": "NO_RECAPTCHA",
"recaptchaVersion": "RECAPTCHA_ENTERPRISE",
"recaptchaToken": "токен"
}
Ответ:
{
"ошибка": {
"код": 400,
"сообщение ": "INVALID_APP_CREDENTIAL",
"ошибки": [
{
"сообщение": "INVALID_APP_CREDENTIAL",
"домен": "глобальный",
"причина": "недействительный"
}
]
}
Это не удалось из-за RECAPTCHA_ENTERPRISE (также пробовал использовать RECAPTCHA_ENTERPRISE в предыдущем проекте Firebase, но не сработало и не включил его в новом проекте Firebase)?
Я также добавлен параметр 127.0.0.1 в настройку аутентификации Firebase в разделе «Авторизованные домены».
Но он не позволяет использовать 127.0.0.1:3000.
Подробнее здесь: https://stackoverflow.com/questions/793 ... al-reactjs