Home > Back-end >  How do I fetch user information to display in a feed of posts using firebase storage solutions?
How do I fetch user information to display in a feed of posts using firebase storage solutions?

Time:10-27

I'm building a forum-style application where users post content that displays on a global feed. I want to display information about the user in posts (photoURL, displayName) similar to Twitter.

I have firebase v9 using the authentication and firestore for the posts. The reason I want to reference the auth is that I can catch changes to the user's information as it happens, this way the feed is up to date.

I save the user's unique ID with the post so I am able to reference who to display. I can successfully reference the post title and description with doc.title & doc.description however I get stuck when retrieving user information. I'm trying doc.UserID.displayName for the display name but I know this is incorrect. I can't find anything in the docs for this specific use case, is this something that I can do with just firestore and auth?

Do I need to create a reference to the auth storage with doc.UserID?

Here is the code:

// add a new post
addPostForm.addEventListener('submit', (e) => {
    e.preventDefault();
    onAuthStateChanged(auth, (user) => {
        const colRef = collection(db, 'Posts');
        console.log(hiddenURL.value);
        addDoc(colRef, {
            UserID: user.uid,
            beatURL: hiddenURL.value,
            title: addPostForm.postTitle.value,
            description: addPostForm.postDescription.value,
        })
            .then(() => {
                console.log("Document written with ID: ", doc.id);
                addPostModal.classList.remove('open');
                addPostForm.querySelector('.error').textContent = "";
            })
            .catch(error => {
                addPostForm.querySelector('.error').textContent = error.message;
                alert(error);
            })
    })
});

export const initApp = async () => {
  initFirebaseAuth;

  const posts = await collection(db, 'Posts');
  // render data to the page
  return renderPosts(posts);
};

const renderPosts = (posts) => {
  const main = document.getElementById("feed");

  onSnapshot(posts, (snapshot) => {
    let cardsArray = []
    snapshot.docs.forEach((doc, user) => {
      cardsArray.push({ ...doc.data(), id: doc.id })

      name.textContent = `${doc.UserID.displayName}`; // users display name
      avatar.src = doc.UserID.photoURL; //user's image
      description.textContent = `${post.description}`;
      title.textContent = `${post.title}`; 

    });
    console.log(cardsArray);
  });
};

CodePudding user response:

There are two cases and approaches at first sight:

1. Your users profiles are only available in the Auth Service

In this case, via the JS SDK, a user X cannot "query" the Auth profile of a user Y.

This means that you need to save the author's displayName together with the author uid when the post is created.

2. Your users profiles are also available in a users collection (a common pattern)

In this case, when you display a post, you could fetch the user's document to get the author's displayName.

However, in the NoSQL world, you should not be afraid to duplicate data and denormalize your data model. When designing your data-model you should think about it from a query perspective, trying to minimize the number of queries for a given screen/use case. So approach #1 is recommended, even if you maintain a user's collection.

In case of changes in the user's profile, in order to synchronyse the post documents and user's data a common approach is to use a set of Cloud Functions (which are executed in the back-end) to update the post documents. The link between the posts and the users profile being the user's uid.

  • Related