Home > Enterprise >  TypeError: Cannot read properties of undefined (reading 'send') | Discord JS v14
TypeError: Cannot read properties of undefined (reading 'send') | Discord JS v14

Time:01-12

I am making a discord bot that will automatically post a message once a document is added or modified in Firebase Firestore. I have run into an error, saying TypeError: Cannot read properties of undefined (reading 'send') when trying to send a message to the channel.

How can I get the channel with the ID stored in channelID? I have tried the solution in the docs, but with no luck. The channel exists, so I don't understand why this error keeps coming.

Here is my code:

const channelID = "1043109494625935387"
let botChannel

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);

  botChannel = client.channels.cache.fetch().find(channel => channel.id === channelID)
});

const doc = db.collection('announcements');

const observer = doc.onSnapshot(docSnapshot => {
  docSnapshot.forEach(async (doc) => {
    if (doc.data().published === false) {
      await botChannel.send(doc.data().title)
    }
  })
}, err => {
  console.log(`Encountered error: ${err}`);
});

CodePudding user response:

It's because everything inside client.on('ready') runs after you set doc.onSnapshot

When you set the onSnapshot listener, Firestore sends your listener an initial snapshot of the data (when botChannel is still undefined), and then another snapshot each time the document changes.

To solve this, you can move all this inside your callback. Also, you can fetch the channel instead.

client.on('ready', async () => {
  console.log(`Logged in as ${client.user.tag}!`);

  const channelID = '1043109494625935387';
  const botChannel = await client.channels.fetch(channelID);

  db.collection('announcements').onSnapshot(
    (docSnapshot) => {
      docSnapshot.forEach(async (doc) => {
        if (doc.data().published === false) {
          await botChannel.send(doc.data().title);
        }
      });
    },
    (err) => {
      console.log(`Encountered error: ${err}`);
    },
  );
});

CodePudding user response:

It's not recommended to fetch all channels at once. Instead, try fetching a single channel at once like so:

<client>.channels.fetch(SNOWFLAKE_ID)

Alternatively if you have the guild object, this will be faster

<guild>.channels.fetch(SNOWFLAKE_ID)

Do keep in mind that these methods both return a Promise, you might have to resolve it.

These solutions will work because the cache is not always up-to-date. If you want to get a channel it is highly recommended to just fetch it.

  • Related