0

I'm making smth with backed for the first time in my life, so I'm sorry in advance, I'm making a web chat app. I think I managed to deal with authentication (it seems to be working) and now I want to make connect somehow the authentication user names with chat users... so I tried to

 const docRef = await addDoc(collection(database, 'users'), {
        name: user.displayName,
    });
    console.log('Document written with ID: ', docRef.id);
} catch (e) {
    console.error('Error adding document: ', e);
}

but it says user not defined because userCredentials is in the scope of authentications functions... If I paste this code into some function where userCredentials can be found, it says there is some problem with await word...

I want to take userCredential that logged in and use it in the chat app... so I need to link somehow the auth db and the firestore db? or is it done completely differently? Thank you

Could you give a bit of advice? Thank you (edited)

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Eugene1111
  • 27
  • 2
  • 7

1 Answers1

0

If you want to use the user's name, you first need to make sure that your code only runs once the user is signed in. In Firebase you can do that as shown in the documentation on getting the currently signed in user:

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth();
onAuthStateChanged(auth, (user) => {
  if (user) {
    //  your application specific code is below
    const docRef = await addDoc(collection(database, 'users'), {
      name: user.displayName,
    });
    console.log('Document written with ID: ', docRef.id);
  } else {
    // User is signed out
    // ...
  }
})

I'd actually recommend not using addDoc, but basing the document ID on the UID of the user, like this:

if (user) {
  //            get UID from user
  const uid = user.uid;

  // Use as document ID                            
  const docRef = await setDoc(doc(database, 'users', uid), {
    name: user.displayName,
  });

Since document IDs are unique within a collection, this automatically ensures that each user can only have one document in the users collection. It also makes it easier to find a user's document when needed, and makes it easier to ensure users can only edit their own document.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • thanks it seems to work, BUT I get null in the user.displayName (( – Eugene1111 Nov 10 '21 at 06:59
  • the console.log right above setDoc shows that it's "Eugene", but the setDoc sets it to null in the database....why this happens? thank you – Eugene1111 Nov 10 '21 at 07:00
  • I think I know why because it gets executed before the name assigns...emmm but why... – Eugene1111 Nov 10 '21 at 07:06
  • It's hard to be certain without seeing your code, but it sounds like you're struggling with asynchronous behavior. Any code that needs the information about the user needs to be inside the `onAuthStateChanged` callback, or be called from there. Code outside of that callback will run at the wrong time. See for example: https://stackoverflow.com/questions/40688268/why-does-firebase-lose-reference-outside-the-once-function/40688890#40688890 (about a different Firebase product, but it's the same problem with an asynchronous API). – Frank van Puffelen Nov 10 '21 at 15:38
  • Hey @Eugene1111 Any update here? – Frank van Puffelen Nov 17 '21 at 17:56