Idris
Idris

Reputation: 518

Conversion to Firebase 9 from version 7 giving me FirebaseError: Expected type 'DocumentReference', but it was: a custom Query object

I am trying to recreate a chat app clone with firebase version 9 from firebase version 7. I am trying to load the chat messages for the two users when the user navigates to the specific chat.

I have tried everything but can't seem to solve the problem. The following is the old piece of code from firebase version 7

export async function getServerSideProps(context) {
  const ref = db.collection('chats').doc(context.query.id);

  // Prep the messages array for the chat
  const messagesRes = await ref
    .collection('messages')
    .orderBy('timestamp', 'asc')
    .get(); 

  const messages = messagesRes.docs.map((doc) => {
    return {
      ...doc.data(),
      id: doc.id,
    }
  }).map(messages => ({
    ...messages,
    timestamp: messages.timestamp.toDate().getTime(),
  }))

  // Prep the users array for the chat
  const chatRes = await ref.get();
  const chat = {
    ...chatRes.data(),
    id: chatRes.id,
  }

  return {
    props: {
      messages: JSON.stringify(messages),
      chat,
    }
  }
}

function ChatConversation({
  chat,
  messages
}) {
  const [user] = useAuthState(auth);

  const endOfMessagesRef = useRef(null);

  const scrollToBottom = () => {
    endOfMessagesRef.current.scrollIntoView({
      behaviour: 'smooth',
      block: 'start',
    });
  };

  return (
    <>
      <ChatScreen chat={chat} messages={messages} />
    </>
  )
}

Here is the rewritten code in firebase version 9:

export async function getServerSideProps(context) {
  const ref = doc(db, "chats", context.query.id);

  // Prep the messages array for the chat

  const messagesRef = collection(db, 'chats', context.query.id, 'messages');

  const messagesRes = await getDocs(query(messagesRef, orderBy("timestamp", "asc")))

  const messages = messagesRes.docs.map((doc) => {
    return {
      ...doc.data(),
      id: doc.id,
    }
  }).map(messages => ({
    ...messages,
    timestamp: messages.timestamp.toDate().getTime(),
  }))

  // Prep the users array for the chat
  const chatRes = await getDocs(ref);
  const chat = {
    ...chatRes.data(),
    id: chatRes.id,
  }

  return {
    props: {
      messages: JSON.stringify(messages),
      chat,
    }
  }
}

function ChatConversation({
  chat,
  messages
}) {
  const [user] = useAuthState(auth);

  return (
    <>
      <ChatScreen chat={chat} messages={messages} />
    </>
  )
}

What can I do to get rid of this error?

Upvotes: 0

Views: 112

Answers (2)

thegera4
thegera4

Reputation: 100

I guess this is the video from Papa React Whatsapp 2.0, so for everyone struggling with this in firebase v9 (current version as of today), here is how I did it:

export async function getServerSideProps(context) {
  const ref = doc(db, `chats/${context.query.id}`);

  const messagesRef = collection(ref, "messages");
  const q = query(messagesRef, orderBy("timestamp", "asc"));
  const messagesRes = await getDocs(q)

  const messages = messagesRes.docs.map((doc) => {
    return {
      ...doc.data(),
      id: doc.id,
    }
  }).map(messages => ({
    ...messages,
    timestamp: messages.timestamp.toDate().getTime(),
  }))

  const chatRes = await getDoc(ref);
  const chat = {
    ...chatRes.data(),
    id: chatRes.id,
  }

  return {
    props: {
      messages: JSON.stringify(messages),
      chat,
    }
  }
}

And if you are from the future... just make sure to read the firebase docs carefully... they will tell you exactly if some of these methods need to be changed... or maybe ask the AI as it will replace all docs and maybe human programmers forever xD ...who knows...

Upvotes: 1

cc_man
cc_man

Reputation: 106

The messagesRef is a subcollection reference inside a specific document in a chat collection.

const ref = doc(db, "chats", context.query.id);
const messagesRef = collection(ref, 'messages');

This is the same syntax below:

 const messagesRef = collection(doc(db, "chats", context.query.id), 'messages');

Then you can put your query inside a variable

const q = query(messagesRef, orderBy("timestamp", "asc");
const docSnap = await getDocs(q);

Upvotes: 1

Related Questions