"location.protocol" must be http, https or chrome-extension and web storage must be enabled. (auth/operation-not-supported-in-this-environment)

52 views Asked by At

I am new to react native and firebase

I had a issue regard to my app which is a cross-platform app(android, ios). I encounter this issue where i just cannot verify user phone number using the firebase phone authentication

Here is my code:

`import React, { useState, useEffect, useRef } from "react";
import {
  View,
  StyleSheet,
  SafeAreaView,
  Text,
  TouchableOpacity,
  FlatList,
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import {
  sharedStyles,
  windowWidth,
  windowHeight,
} from "../../assets/shared/styles.js";
import Signup_email from "./signup_email.js";
import Signup_email_verify from "./signup_email_verify.js";
import Signup_phone from "./signup_phone.js";
import Signup_phone_otp from "./signup_phone_otp.js";
import Signup_password from "./signup_password.js";
import { firebaseConfig } from "../../config/config.js";
import firebase from "firebase/compat/app";
import firestore from "@react-native-firebase/firestore";
import {
  createUserWithEmailAndPassword,
  sendEmailVerification,
  getAuth,
  PhoneAuthProvider,
  RecaptchaVerifier,
  auth,
  signInWithPhoneNumber,
} from "firebase/auth";
import { FirebaseRecaptchaVerifierModal } from "expo-firebase-recaptcha";

const PaginationDot = ({ index, activeIndex }) => {
  return (
    <View style={[styles.dot, index === activeIndex && styles.activeDot]} />
  );
};

export default function Signup_base() {
  const [activeSlide, setActiveSlide] = useState(0);
  const [isEmailValid, setIsEmailValid] = useState(false);
  const [userEmail, setUserEmail] = useState("");
  const [authUser, setAuthUser] = useState(null);
  const [userPhone, setUserPhone] = useState(null);
  const recaptchaVerifier = useRef(null);
  const [verificationId, setVerificationId] = useState(null);
  const [code, setCode] = useState("");
  const auth = getAuth();

  const handleEmailEntered = (email) => {
    setUserEmail(email);
  };

  const handlePhoneEntered = (phone) => {
    setUserPhone(phone);
  };

  const handleEmailValidated = (isValid) => {
    setIsEmailValid(isValid);
  };

  // Generate data array based on the number of slide functions
  const data = Array.from({ length: 5 }, (_, index) => ({
    key: `Slide ${index + 1}`,
  }));

  useEffect(() => {
    const checkEmailVerification = async () => {
      const auth = getAuth();
      const user = auth.currentUser;

      if (user) {
        await user.reload();

        if (user.emailVerified && activeSlide === 1) {
          // User's email is verified, proceed to the next slide
          setAuthUser(user);
          const nextIndex = (activeSlide + 1) % data.length;
          setActiveSlide(nextIndex);
        }
      }
    };

    const intervalId = setInterval(() => {
      checkEmailVerification();
    }, 1000); // Check every 1 seconds

    return () => clearInterval(intervalId); // Clear interval on component unmount
  }, [activeSlide]);

  const getSlideComponent = (index) => {
    switch (index) {
      case 0:
        return (
          <Signup_email
            onEmailEntered={handleEmailEntered}
            onEmailValidated={handleEmailValidated}
          />
        );
      case 1:
        return <Signup_email_verify email={userEmail} />;
      case 2:
        return <Signup_phone onPhoneEntered={handlePhoneEntered} />;
      case 3:
        return <Signup_phone_otp />;
      case 4:
        return <Signup_password />;
      default:
        return <></>;
    }
  };

  const handleSignup_email = async () => {
    if (
      !(
        userEmail === null ||
        userEmail === undefined ||
        userEmail === "" ||
        !isEmailValid
      )
    ) {
      try {
        // Create a user with a temporary password
        const tempPassword = Math.random().toString(36).slice(-8);
        const { user } = await createUserWithEmailAndPassword(
          auth,
          userEmail,
          tempPassword
        );

        // Send email verification
        sendEmailVerification(user);

        await auth.onAuthStateChanged((user) => {
          if (user) {
            setAuthUser(user);
            // Navigate to the next screen or perform any desired action
            const nextIndex = (activeSlide + 1) % data.length;
            setActiveSlide(nextIndex);
          }
        });
      } catch (error) {
        if (error.code === "auth/email-already-in-use") {
          // Handle case where the email is already in use
          alert(
            "This email address is already registered. Please use a different email."
          );
        } else {
          // Handle other errors
          console.error("Error creating user:", error.message);
        }
      }
    } else if (
      !isEmailValid &&
      !(userEmail === undefined || userEmail === null || userEmail === "")
    ) {
      alert("The entered email format is invalid.");
    } else if (
      userEmail === undefined ||
      userEmail === null ||
      userEmail === ""
    ) {
      alert("Please enter a valid email.");
    }
  };

  const handleSignup_email_verification = async () => {
    const auth = getAuth();
    const user = auth.currentUser;
    await user.reload();

    sendEmailVerification(user);
  };

  const newRecaptchaVerifier = () => {
    return new firebase.auth.RecaptchaVerifier("recaptcha-container", {
      size: "invisible",
      callback: (response) => {
        // Recaptcha callback
      },
    });
  };

  const handleSignup_phone = async () => {
    // const appVerifier = newRecaptchaVerifier();
    // try {
    //   const confirmation = await signInWithPhoneNumber(auth, userPhone, appVerifier);
    // } catch (error) {
    //   console.error(error);
    // }

    // const result = await signInWithPhoneNumber(
    //   auth,
    //   userPhone,
    //   recaptchaVerifier.current
    // );

    // const phoneProvider = new firebase.auth.PhoneAuthProvider();
    // phoneProvider

    //   .verifyPhoneNumber(userPhone, recaptchaVerifier.current)
    //   .then(setVerificationId);
    //   setUserPhone("");

    if (userPhone) {
      try {
        const phoneAuthProvider = new firebase.auth.PhoneAuthProvider(auth);
        const recaptchaVerifier = newRecaptchaVerifier(); // Create a new RecaptchaVerifier
        const verificationId = await signInWithPhoneNumber(
          phoneAuthProvider,
          userPhone,
          recaptchaVerifier
        );

        // Move to the next slide
        const nextIndex = (activeSlide + 1) % data.length;
        setActiveSlide(nextIndex);
      } catch (error) {
        console.error("Error sending SMS verification code:", error.message);
      }
    } else {
      alert("Please enter a valid phone number.");
    }
  };

  // const confirmCode = () => {
  //   const credential = firebase.auth.PhoneAuthProvider.credential(
  //     verificationId,
  //     code
  //   );
  //   firebase.auth().signInWithCredentials(credential)
  //   .then(() => {
  //     setCode('');
  //   })
  //   .catch((error) => {
  //     alert(error);
  //   })
  //   Alert.alert("")
  // }

  return (
    <SafeAreaView style={styles.container}>
      <View>
        {/* Pagination Dots */}
        <View style={styles.paginationContainer}>
          <FlatList
            data={data}
            horizontal
            showsHorizontalScrollIndicator={false}
            pagingEnabled
            keyExtractor={(item, index) => index.toString()}
            renderItem={({ index }) => (
              <PaginationDot index={index} activeIndex={activeSlide} />
            )}
          />
        </View>
      </View>

      {/* Render the appropriate slide component based on the active slide */}
      {getSlideComponent(activeSlide)}

      {/* Additional Signup content */}
      <TouchableOpacity
        onPress={() => {
          handleSignup_phone();
          // const nextIndex = (activeSlide + 1) % data.length;
          // setActiveSlide(nextIndex);
          // if (activeSlide === 0) {
          //   handleSignup_email();
          // } else if (activeSlide === 1) {
          //   handleSignup_email_verification();
          // } else if (activeSlide === 2) {
          //   handleSignup_phone();
          // }
        }}
      >
        <LinearGradient
          colors={["#5899E2", "#12B3CA"]}
          style={[sharedStyles.button, { width: windowWidth * 0.8 }]}
          start={{ x: 0, y: 0.5 }}
          end={{ x: 1, y: 0.5 }}
        >
          {activeSlide !== 1 && (
            <Text style={sharedStyles.buttonText}>Next</Text>
          )}
          {activeSlide === 1 && (
            <Text style={sharedStyles.buttonText}>
              Resend Verification Email
            </Text>
          )}
        </LinearGradient>
      </TouchableOpacity>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "flex-start",
    flexDirection: "column",
    alignItems: "center",
  },
  paginationContainer: {
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
    marginTop: windowHeight * 0.02,
  },
  dot: {
    width: 15,
    height: 15,
    borderRadius: 50,
    backgroundColor: "#BDBDBD", // Inactive dot color
    marginHorizontal: windowWidth * 0.03,
    alignSelf: "center",
  },
  activeDot: {
    backgroundColor: "#2196F3", // Active dot color
    width: 20,
    height: 20,
    alignSelf: "center",
  },
});
`

I want the user to receive a SMS using the firebase phone auth with 6-digit and user will able to use the number receive to verify thier phone number. This should work for both android and ios.

1

There are 1 answers

4
Rainy sidewalks On

please go through below ,modify it accordingly your need and let m know any

import React, { useState } from 'react';
import firebase from 'firebase/app';
import 'firebase/auth';

const VerifyPhoneNumber = () => {
  const [phoneNumber, setPhoneNumber] = useState('');
  const [verificationCode, setVerificationCode] = useState('');

  const handleSendVerificationCode = () => {
    const appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
      .then((confirmationResult) => {
        const verificationId = confirmationResult.verificationId;
        // here store verificationId for later use
      })
      .catch((error) => {
        console.error(error.message);
      });
  };

  const handleVerifyCode = () => {
    const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    firebase.auth().signInWithCredential(credential)
      .then((userCredential) => {
        //success phone number verified 
      })
      .catch((error) => {
        //pass error to user 
         console.error(error.message);
      });
  };

  return (
    <div>
      <input type="text" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} />
      <button onClick={handleSendVerificationCode}>Send Verification Code</button>
      <input type="text" value={verificationCode} onChange={(e) => setVerificationCode(e.target.value)} />
      <button onClick={handleVerifyCode}>Verify Code</button>
      <div id="recaptcha-container"></div>
    </div>
  );
};

export default VerifyPhoneNumber;

read environments-js-sdk#polyfills

Polyfills The Firebase JavaScript SDK is built on the latest standards of the web platform. Some older browsers and JavaScript environments do not support all the features required by Firebase. If you must support these browsers/environments, then you need to load polyfills accordingly.