Daniel Bílek
Daniel Bílek

Reputation: 85

ReactJS/Firebase: TypeError: Cannot read properties of undefined (reading 'indexOf')

i am getting this error: Uncaught TypeError: Cannot read properties of undefined (reading 'indexOf')

It happens only if i reload the page. On the first load its ok, when i reload it happens.

I tried do something like: favoritesItems?.map((favorite) => .... and doesnt help, so i think it might be problem in auth?

EDIT: If i delete const { user } = UserAuth() and hard code UserID, everything works even after reload

Favorites.js

    function Favorites() {
    
      const [favoritesItems, setFavoritesItems] = React.useState([])
      const { user } = UserAuth();
      const UserID = user.uid
      const favoritesRef = doc(db, "favorites", UserID)
    
      
      const unsub = onSnapshot(doc(db, "favorites", UserID), (doc) => {
        setFavoritesItems(doc.data().favs);
    });
    
    
    const removeFav = async (name) => {
      await updateDoc(favoritesRef, {
        favs: arrayRemove({"name": name.name, "ytb": name.ytb, "url": name.url})
    });
    
    }
        
      return (
        <div className="container mx-auto px-5 py-10">
        <h2 className="text-xl lg:text-3xl uppercase tracking-wider">My favorites collection</h2>
    
        <div className="flex flex-col items-center sm:items-start gap-10 mt-5 sm:grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
        {favoritesItems?.map((favorite) => (
    
          <div key={favorite.name} className="flex flex-col gap-2 w-64 md:w-72 ">
              <iframe src={favorite.url} title={favorite.name} allowFullScreen className="w-full" />
              <h1  className="font-light">{favorite.name}</h1>
              <div className="flex justify-between gap-3">
                <a href={favorite.ytb} target="_blank"><ExternalLinkIcon className="w-5 cursor-pointer" /></a>
                <TrashIcon onClick={() => removeFav(favorite)} className="w-5 cursor-pointer" />
              </div>
          </div>
    
          )) }
        </div>
        </div>
      )
    }
    export default Favorites

AuthContext.js

const UserContext = createContext();

export const AuthContextProvider = ({ children }) => {
   const [user, setUser] = useState({});

   const signIn = (email, password) =>  {
    return signInWithEmailAndPassword(auth, email, password)
   }

   const createUser = (email, password) => {
    return createUserWithEmailAndPassword(auth, email, password);
  };

   const logout = () => {
     return signOut(auth)
   }


   useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
    });
    return () => {
      unsubscribe();
    };
  }, []);



  return (
    <UserContext.Provider value={{ createUser, signIn, user, logout }}>
      {children}
    </UserContext.Provider>
  );
};

export const UserAuth = () => {
  return useContext(UserContext);
};

Upvotes: 3

Views: 2040

Answers (3)

Chen Peleg
Chen Peleg

Reputation: 2124

Don't know if it helps but I got the same unclear error when there was a problem in my Document reference (because the document Id was undefined). So if anyone else get this, first check the doc Id & reference are valid.

Upvotes: 0

Bob the Builder
Bob the Builder

Reputation: 185

You should use ""react-firebase-hooks/auth". It makes saving the currently logged in user's auth a lot easier across your application. Import from it like this: import { useAuthState } from "react-firebase-hooks/auth";

Get the auth variable from import { auth, db } from "../../config/firebase";, you can pass it into useAuthState hook like this const [user] = useAuthState(auth);.

I might be late but I had this same error message with indexOf. My problem was different.

What I was doing wrong was that I was expecting a field to be in a document. But the problem was when adding that document to the collection, I forgot to pass a field in.

The field I wanted to pass in was the document ID of the document after it gets created, so I don't actually have this field when creating the document but only after. After creating the doc, you have to get the snapshot you get as the return from addDoc(), get the id property from that, then use updateDoc() to add the documentID to the document you just created. Example code:

      const commentSnapshot = await addDoc(commentsRef, {
        postId: postId,
        comment: comment,
        name: name,
        userId: user?.uid
      });

      const commentId = commentSnapshot.id;
      const commentDocRef = doc(commentsRef, commentId);
      await updateDoc(commentDocRef, { commendId: commentId });

Upvotes: 0

mahdi pakravan
mahdi pakravan

Reputation: 41

there isn't any usage of indexOf in your code

It may be for two reasons :

  1. You're using indexOf in your code but it's not here (in your sent screenShots), may in another file ! so you can use "? character" to solve this . ex : item?.availablity?.indexOf("Jhones"); you can use deep search with your IDE to find indexOf in all of your code

  2. a module is using indexOf in moduleCodes for example you are passing a data to Firebase and firebase want to find indexOf something in this data but fireBase didn't found that.

  • you can create an issue to firebase repository and ask to solve this
  • you can clone this repository , fix this and use deploy on a local npm and use it with your fixed code
  • you can declare the function in your codebase

Upvotes: 1

Related Questions