Why does my function continue executing before my asynchronous process has finished? [duplicate]

I’m implementing Firebase Cloud Messaging for an app for shops I am building.

After getting a message from a client, I would like to notify all the admins of that shop. For that, I fetch the doc of shop that the message was sent to, grab an array with the IDs of all the admins, and then for each ID (uid) I fetch the token which I’ve stored in firestore.
All the tokens get pushed into an array, and once I am done gathering all the tokens, I start sending the notifications.

The problem I am facing is that the function continues without waiting for the tokens to be fetched, so it evaluated the tokens array to be empty and finishes without sending any notification.

I know it because of logs I’ve added.
This is my cloud function:

exports.sendNotifications = functions.firestore
  .document("messages/{messageId}")
  .onCreate(async (snapshot) => {
    // Notification details.    
    let text = snapshot.data().message_body || "";
    if (text.length > 100) {
      text = text.substring(0, 97) + "...";
    }
    const payload = {
      notification: {
        title: `הודעה חדשה מ${snapshot.data().name}`,
        body: text,
        // icon:
        //   snapshot.data().profilePicUrl || "/images/profile_placeholder.png",
        // click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
      },
    };

    const shopID = snapshot.data().shop_id;

    const shopData = await admin
      .firestore()
      .collection("shops")
      .doc(shopID)
      .get();
    const shopAdminsArray = shopData.data()?.admins;
    console.log("shopAdminsArray is ", shopAdminsArray);

    const tokens: string[] = [];

    shopAdminsArray.forEach(async (shopAdmin: string) => {
      const user = await admin
        .firestore()
        .collection("fcm_tokens")
        .doc(shopAdmin)
        .get();

      console.log("user.data()?.token is ", user.data()?.token);

      if (user.data()?.token) {
        tokens.push(user.data()?.token);
      }
    });

    console.log("tokens.length is ", tokens.length);

    if (tokens.length > 0) {
      // Send notifications to all tokens.
      const response = await admin.messaging().sendToDevice(tokens, payload);
      await cleanupTokens(response, tokens);
      functions.logger.log(
        "Notifications have been sent and tokens cleaned up."
      );
    }
  });

I consistently get the log saying tokens.length is 0 and only after that a log saying user.data()?.token is xxxxxxxxxxxxx