Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fredy-rizo/ecommerce-delivery-frontend/llms.txt

Use this file to discover all available pages before exploring further.

Ecommerce Delivery delivers notifications through two complementary channels: Firebase Cloud Messaging (FCM) for browser push notifications and a REST-backed in-app feed. When a user grants notification permission in the browser, the app registers a device token with the backend so the server can push notifications to that device even when the tab is not in focus. Users can also browse all past notifications from the dedicated /notifications page, which uses infinite scroll to load them from the API.

Firebase Cloud Messaging (FCM)

Configuration

src/firebase/init.js initialises the Firebase compat SDK using environment variables for every sensitive value:
import firebase from "firebase/compat/app";
import "firebase/compat/messaging";

const firebaseConfig = {
  apiKey:            process.env.API_KEY,
  authDomain:        process.env.AUTH_DOMAIN,
  projectId:         process.env.PROJECT_ID,
  storageBucket:     process.env.STORAGE_BUCKET,
  messagingSenderId: process.env.MESSAGING_SENDER_ID,
  appId:             process.env.APP_ID,
  measurementId:     process.env.MEASUREMENT_ID,
};

firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

export { firebase, messaging };
The file exports both the firebase instance and the messaging object so other modules can import them directly.

Background notifications

Background push notifications (received when the tab is not active or the browser is minimised) are handled by the service worker at public/firebase-messaging-sw.js. The service worker must be registered separately and kept in sync with the Firebase SDK version used in the app.

FCM token registration flow

1

User signs in

The user completes sign-in successfully and a valid session token is stored locally.
2

Request notification permission

After login, Notification.requestPermission() is called. The browser shows its native permission prompt to the user.
3

Retrieve FCM token

If the user grants permission, getToken(messaging, { vapidKey }) is called to retrieve the device-specific FCM token:
import { getToken } from "firebase/messaging";
import { messaging } from "src/firebase/init";

const fcmToken = await getToken(messaging, {
  vapidKey:
    "BIuq4uj12vyVbY9Nb5T58OoCO68yps6FrB1OEv6X5DD8sl1Pt7H2Ie94ZqYAezPzoyjAMA-ncTnM3lFolK2EKq8",
});
4

Register token with backend

The token is posted to the backend so the server can associate it with the authenticated user:
await fetch(`${process.env.API_SERVER}/api/notification/register-token`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${sessionUser.token}`,
  },
  body: JSON.stringify({ userId, fcmToken }),
});
The VAPID key used in getToken() is currently hardcoded inside formSignIn.vue (value shown above). For production deployments it should be moved to an environment variable (e.g. process.env.VAPID_KEY) to avoid exposing it in source control.
Notification permission must be explicitly granted by the user in the browser. If the user clicks Block or dismisses the prompt, Notification.requestPermission() returns "denied" and no FCM token will be registered. The app will still function normally, but the user will not receive push notifications.

In-app notification feed

Route

/notifications renders pages/notifications/Notifications.vue, which is a thin wrapper that mounts ListNotifications:
<template>
  <div>
    <h5 class="q-px-md">Notificaciones</h5>
    <ListNotifications />
  </div>
</template>

Infinite scroll fetch

ListNotifications uses q-infinite-scroll to lazily load notifications in pages of 10. Each scroll event calls listNotifications(index, done), which increments the page counter and fires getNotifications():
const getNotifications = async () => {
  const sessionUser = validateUser({ rol: 1 });
  let res = await fetch(
    process.env.API_SERVER +
      `/api/notifications/list/${pagination.value.pag}/${pagination.value.perpage}`,
    {
      method: "POST",
      mode: "cors",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Basic " + sessionUser.token,
      },
      body: JSON.stringify({}),
    }
  );
  res = await res.json();
  ValidateSession(res, router);
  return res;
};
New pages are pushed onto the notifications reactive array and pagination.pags is updated from the server’s response. Scrolling stops when pagination.pags === pagination.pag.

ItemNotification

Each notification in the list is rendered by the ItemNotification component, which receives the notification object as the notify prop:
<q-item>
  <q-item-section>
    <q-item-label>{{ notify.title }}</q-item-label>
    <!-- Truncates description at 50 chars with "Ver mas" toggle -->
    <q-item-label caption lines="2" @click="showDescription = !showDescription">
      {{ notify.description.slice(0, 50) }}
    </q-item-label>
  </q-item-section>

  <q-item-section side top>
    <q-item-label caption>{{ notify.createdAt.slice(0, 10) }}</q-item-label>
  </q-item-section>
</q-item>
Descriptions longer than 50 characters are truncated by default. Clicking the caption or the Ver mas link expands the full text; clicking again collapses it back.

Build docs developers (and LLMs) love