1

The first time a user logins with Google Auth provider a "username" field with an empty value is set in Users collection user.uid document. Now I want to first check if the username length is greater than 3 (which will be the minimum for a username). If greater than 3 usernames are already set, else a modal should open for the user to set a username.

The code below does not work and not sure if it's the correct approach I was trying. The code runs once the user logs in.

  const [user] = useAuthState(auth);

  const CheckUsername = async () => {

    const docRef = doc(db, "UsersData", user.uid);
    const docSnap = await getDoc(docRef);

    if (!docSnap.exists() && docSnap.data().username.length > 3) {
      //<Show SetUserName Modal - Recoil>
    } else if (docSnap.exists() && docSnap.data().username.length > 3) {
      //<Don't show SetUserName Modal>
    }
  };

  useEffect(() => {
    if (user) {
      CheckUsername();
    }
  }, [user]);

SetUsername Modal:

  const [user] = useAuthState(auth);

  const [usernameValue, setUsernameValue] = useState("");

  const SetUsername = async () => {
    try {
      const UserRef = collection(db, "UsersData")
      const UsernameQuery = query(UserRef, where("username", "==", usernameValue))

      const Username = await getDoc(UsernameQuery)

      if(!Username.exists()) {

        await updateDoc(doc(db, "UsersData", user.uid), {
          username: usernameValue,
        });

      } else {
          console.log("Username already exists, please try another one");
      }
    } catch (error) {
      console.log("error in try catch")
    }
  }

  return (
    <div>
      <input type="text" onChange={(e) => setUsernameValue(e.target.value)} />
      <button onClick={SetUsername}>Set username</button>
    </div>
  );
Sadeed_pv
  • 513
  • 1
  • 9
  • 22
Mintee
  • 505
  • 4
  • 22

1 Answers1

1

Solution I came up with:

This is in layout:

  const [user] = useAuthState(auth);

  const [open, setOpen] = useRecoilState(setUsernameModal);

  const [update, setUpdate] = useState(true);

  const CheckUser = async () => {
    try {
      //Where Users are stored
      const userDocRef = doc(db, "UsersData1", user.uid);

      //Using Transaction for if something goes wrong mid process no action taken at all
      await runTransaction(db, async (transaction) => {
        const userDoc = await transaction.get(userDocRef);

        //Read ELSE first
        //If userDoc exists means they logged in before AND/OR never finished the registration process
        if (userDoc.exists()) {
          const User = await getDoc(userDocRef);

          //if usernameSet = false means they never set the username before
          if (User.data().usernameSet === false) {
            //Opens a modal to set username - (for my case it's the last process for registration)
            setOpen(true);
          }
        } else {

          //If User doesn't exist in "UsersData" means it's the first time they are logging in
          await setDoc(doc(db, "UsersData1", user.uid), {

            //usernameSet to check if username is set or not.
            usernameSet: false,
            username: "",

            //usernameValue for search if username is taken and should be in uppercase OR lowercase since Fx: John & john are not the same
            usernameValue: "",
            //Add's default Firebase info
            user: JSON.parse(JSON.stringify(user)),
          });

          //Updates useEffect so the user falls in userDoc.exists
          setUpdate(!update);
        }
      });
    } catch (error) {}
  };

  useEffect(() => {
    if (user) {
      CheckUser();
    }
  }, [user, update]);

Then a modal to update: username: "" and usernameSet: to true and then use usernameValue to check if user already exists

Mintee
  • 505
  • 4
  • 22