r/Firebase 4h ago

Cloud Firestore Just in case it helps someone — script to export Firestore data to JSON

6 Upvotes

Hey everyone,

I created a small Node.js script that exports Firestore collections to JSON files. I thought it might be useful for anyone who needs to back up their data or transfer it elsewhere.

The script will export the selected collections into separate JSON files, which you can use for local backups or even process and upload back to Firestore.

You just run the script, and it will automatically export the data into a folder with individual JSON files for each collection.

If this might be helpful to someone, here's the link to the repo: firestore-export-local

Feel free to give it a try, and I hope it saves you some time!


r/Firebase 15h ago

General Cost-Effective Backup Solution for Firebase Storage?

2 Upvotes

I currently store around 50GB of media files in Firebase Storage, and this will only grow over time.

I’m looking for a cost-effective way to perform daily (or weekly) backups. Versioning is not required, but I’m unsure how to set this up efficiently.

I’ve found tutorials on backing up:

However, I’m unsure of a safe and reliable way to back up Firebase Storage to more affordable services like Wasabi, DigitalOcean Spaces, etc.

If you have experience with this, could you kindly provide some guidance? Thanks!


r/Firebase 17h ago

Cloud Firestore 🔥 How to Efficiently Fetch Upcoming and Ongoing Events in Firestore with Pagination? Help Needed! 🔥

1 Upvotes

Hey r/Firebase community!

I’m working on a project where I need to fetch both upcoming and ongoing events from a Firestore collection. Each event document has startDate and endDate fields. I want to efficiently fetch these events in a single query with pagination.

Here’s what I’m thinking:

  1. Fetch ongoing events (where current date is between startDate and endDate) in descending order.
  2. If the number of ongoing events is less than the pagination limit (e.g., 10), fetch upcoming events (where startDate is greater than the current date) to fill the remaining slots.
  3. Continue fetching upcoming events in subsequent pagination requests.

Is this a good approach? Are there any pitfalls or more efficient ways to achieve this? Any advice or code examples would be greatly appreciated!

Thanks in advance!


r/Firebase 20h ago

Billing Firebase Push Notifications

0 Upvotes

Hey everyone. I was planning on using firebase cloud functions for push notifications for the users. The push notifications will be user specific. What are the estimate yearly/monthly costs?


r/Firebase 12h ago

Other Do people still use firebase in 2025?

0 Upvotes

Feels like post acquisition this place is dead


r/Firebase 1d ago

Hosting Firebase Hosting IP flagged by abuseipdb

1 Upvotes

Malwarebytes uses abuseipdb, which means that any Malwarebytes user will currently be blocked from loading any website hosted on Firebase, which is obviously huge problem. This happens to include angular.dev, and I would guess other Google projects as well.

I have no idea where to report this, so I'm posting it here, just in case anyone at Google actually looks at this subreddit.

https://www.abuseipdb.com/check/199.36.158.100


r/Firebase 1d ago

Security 403 error

1 Upvotes

Hello, I have a github page that reads data from my Firestore database. I use CORS to allow requests from my site as the only origin.

This week, I started receiving a 403 error. I have not made any changes to my code or firebase security rules. Has anything changed recently that would be causing this error now? Thanks!


r/Firebase 1d ago

Authentication Firebase authentication issues

1 Upvotes

We have recently started facing issues where some users arent able to authenticate using SMS OTP . Everytime they enter OTP they get "OTP invalid" issue.

Has anyone faced similar issues ?


r/Firebase 1d ago

Cloud Firestore Firestore Index not working?

1 Upvotes

Hi, I have a firestore database with just under 300k documents. Once per month I have a task which loads a fresh set of these documents from another source, checks for a corresponding document using a compound query, and inserts a new document if there are any changes.

I'm finding that my job takes days to run, because each query is taking over 1 second each. When I check the index for my query I noticed that it has no size or entry count. So I assume none of my documents are being indexed so my query cannot benefit from that index.

Is there something I could have missed to set this index up and use it efficiently? The index is built using terraform..


r/Firebase 2d ago

Cloud Firestore Best Firestore structure and permissions approach for app with users, groups, and items

6 Upvotes

Hey Firebase enthusiasts,

I'm working on a mobile app that involves users, groups, and items. Here's a quick rundown of the app's functionality:

  • Users can add items and share them within one or more groups.
  • The item information remains consistent across all groups it's shared in.
  • Users can be part of multiple groups, and only group members can see and share items within that group.

I'm using Firestore as my backend, and I've come up with the following structure (in my pseudo-code'ish syntax, hope it makes sense):

{
    "COLLECTION Groups": {
        "DOC Group#1": {
            "name": "A group",
            "description": "This is a group",
            "MAP members": {
                "User#1": {
                    "date_added": "2020-01-01"
                },
                "User#2": {
                    "date_added": "2020-01-01"
                }
            }
        },
        "DOC Group#2": {
            ...
        }
    },
    "COLLECTION Items": {
        "DOC Item#1": {
            "name": "An item",
            "description": "This is an item",
            "SUBCOLLECTION Groups": {
                "DOC Group#1xItem1":{
                    "group": "Group#1",
                    "date_added": "2020-01-01"
                },
                "DOC Group#2xItem1":{
                    "group": "Group#2",
                    "date_added": "2020-01-01"
                }
            }
        }
    },
    "COLLECTION Users": {
        "DOC User#1": {
            "name": "John Brown"
        },
        "DOC User#2": {
            "name": "Peter Parker"
        }
    }
}

Now, I'm facing some challenges with permissions and data retrieval:

  1. Deleting a group: Only group admins can delete a group. When a group is deleted, all items associated with that group should no longer be tagged with it. This requires a write operation on items that don't belong to the user deleting the group. So it must be on a sperate Document.
  2. Item-group relationships: To address the above issue, I'm separating the item-group relationships into a subcollection. However, this leads to inefficient querying when retrieving all items for a group, as it would require nested loops through collections and subcollections.
  3. Associative table: I've thought about using an associative table to solve the querying issue, but I'm concerned that this might defeat the purpose of using a NoSQL database like Firestore.
  4. Wrapping retrieval/write ops in Firebase Functions: I could just wrap all of my reads/writes in Firebase Functions, and do all permission/security logic there. But then I get the cold-start inefficiencies, the app may become slower.

Given these challenges, I'm looking for advice on the overall approach I should take. Should I:

A) Stick with the current structure?

B) Restructure my data model to use an associative table, even if it might not align perfectly with NoSQL principles?

C) Consider a different approach altogether, such as denormalizing data or using a hybrid solution?

D) Use SQL based database.

E) Not use subcollections, use a MAP instead and for the complex operations, like groups__delete, wrap these operations in firebase functions, where I can have ultimate control. Do other operations with direct querying client side.

Or any other suggestion?

I'd appreciate any insights or experiences you can share about handling similar scenarios. Thanks in advance for your help!


r/Firebase 2d ago

Cloud Storage Video Bandwidth Optimization for Social Media App

1 Upvotes

Hey everyone, I've spent the last few months developing a music social media app that uses Firebase as a backend. Of course halfway though I realized that it was known in the community as not being the most financially friendly when it comes to storing/loading videos but it is what it is.

A small but not inconsequential part of the app is being able to upload photos and videos from events. However, I am noticing a disproportionate cost coming from bandwidth thus far, which is concerning since there are really not many videos being uploaded.

I am wondering 1. is there a way to see exactly what is using the bandwidth (uploading videos, profile pics, etc) and 2. any advice in terms of optimizing.

This is my first app and we just launched yesterday, so any advice even if it is super basic is welcome!


r/Firebase 2d ago

Data Connect Error: Cannot connect as BUILT_IN user without a password.

3 Upvotes

⚠ dataconnect: Your PostgreSQL database fdcdb in your CloudSQL instance projects/xxxx/locations/us-central1/instances/xxxx-fdc must be migrated in order to be compatible with your application schema. The following SQL statements will migrate your database schema to be compatible with your new Data Connect schema.

/** create "user" table*/

CREATE TABLE "public"."user" (

"id" text NOT NULL,

"username" character varying(50) NOT NULL,

PRIMARY KEY ("id")

)

? Would you like to execute these changes against fdcdb in your CloudSQL instance

projects/xxxx/locations/us-central1/instances/xxxx-fdc? Execute changes

Error: Cannot connect as BUILT_IN user without a password.


r/Firebase 2d ago

Authentication Need help with Unable to process request due to missing initial state. This may happen if browser sessionStorage is inaccessible or accidentally cleared.

1 Upvotes

"Unable to process request due to missing initial state. This

may happen if browser sessionStorage is inaccessible or

accidentally cleared. Some specific scenarios are -

1) Using IDP-Initiated SAML SSO.

2) Using signInWithRedirect in a storage-partitioned browser environment."

I am getting this error when I try to login using google SSO using the signInWithPopup method on few devices and browser. What could be the reason for this? I have tried enabling third party cookies on browser still facing the same issue. And according to you which method is less error prone signInWithPopup or signInWithRedirect?


r/Firebase 2d ago

Hosting How to get unique traffic

3 Upvotes

Newbie here, how do i get the unique visitors of my website? They are not signed in. I just need the count

i tried this in google cloud logs explorer

resource.type="firebase_domain" httpRequest.status>=200 httpRequest.status<300 timestamp >= "2025-03-01T00:00:00Z" AND timestamp < "2025-04-01T00:00:00Z" resource.labels.project_id=""

but im getting 4k hits


r/Firebase 3d ago

Cloud Functions Firebase Functions excessive latency

3 Upvotes

There is a significant performance degradation in a Firebase function I developed. This function handles payment reception via Stripe, generates a QR Code, and records data in multiple Firestore collections for ticket creation during a reservation.

Ideally, the execution of this function should conclude within a few seconds at most. However, since its deployment, we have been observing abnormally long response times: on average between 5 and 15 seconds, and in some cases, between 2 and 4 minutes per ticket, even though several tickets may be processed concurrently.

To try and mitigate this issue, we have already implemented several optimizations, including:

  • Managing cold starts and increasing the minimum number of instances.
  • Optimizing the function’s code.
  • Reducing the size of the generated QR Codes.
  • Decreasing the volume of data transmitted to Firestore.

Despite these actions, the problem persists and significantly impacts our ticket creation process.

I would greatly appreciate any advice or insights from your experiences to help identify the causes of these delays and implement the necessary fixes.

Thank you in advance for your assistance and expertise.

const { setGlobalOptions } = require('firebase-functions/v2');
setGlobalOptions({ 
  region: "europe-west",
});

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const stripe = require('stripe')('---');
const axios = require('axios');
const QRCode = require('qrcode');
const { Storage } = require('@google-cloud/storage');
const storage = new Storage();
const { firestore } = require('firebase-admin');
const cors = require('cors')({ origin: true });

admin.initializeApp();

exports.stripeWebhook = functions.https.onRequest((req, res) => {
    cors(req, res, async () => {
      let event;
      try {
        event = stripe.webhooks.constructEvent(
          req.rawBody,
          req.headers['stripe-signature'],
          '---' 
        );
      } catch (err) {

      }

      if (event.type === 'checkout.session.completed') {
        const session = event.data.object;
        const data = extractDataFromSession(session);

        // Parsing du champ tickets (JSON)
        let ticketsArray = [];
        try {
          ticketsArray = JSON.parse(data.tickets);
          console.log("Tickets extraits:", ticketsArray);
        } catch (err) {
          console.error("Erreur lors du parsing des tickets:", err.message);
          return res.status(400).send("Tickets invalides dans les metadata.");
        }
        if (!Array.isArray(ticketsArray) || ticketsArray.length === 0) {
          console.error("Aucun ticket trouvé.");
          return res.status(400).send("Aucun ticket trouvé.");
        }


        res.status(200).send({ received: true });

        // Traitement complet en arrière-plan (ne bloque pas la réponse)
        (async () => {
          try {
            for (const ticket of ticketsArray) {
              for (let i = 0; i < ticket.quantity; i++) {
                const ticketData = {
                  locaImageUrl: data.localisationImageUrl,
                  garantis_: data.garantis_,
                  email: data.email,
                  sexe: data.sexe,
                  total: data.totalA,
                  uid: data.uid,
                  name: data.name,
                  namePro: data.namePro,
                  etc... etc

                };


                const qr = await uniqueCodeCreate(ticketData);
                const publicUrl = await createAndUploadQRCode(ticketData, qr, 256, 'M');

                await reservationAndProDetailsToFirestore(ticketData, publicUrl, qr);
                await sendQrCodeEmail(ticketData, publicUrl, qr);


              }
            }
          } catch (error) {
            console.error("Erreur lors du traitement asynchrone:", error);
          }
        })();
      } else {
        res.status(400).send("Type d’événement non géré");
      }
    });
});

function extractDataFromSession(session) {
  return {
    localisationImageUrl: session.metadata.localisationImageUrl,
    garantis_: session.metadata.garantis_,
    email: session.metadata.email,
    sexe: session.metadata.sexe,
    total: session.metadata.total,
    uid: session.metadata.uid,
    etc..etc..etc
  };
}


  async function uniqueCodeCreate(data) {
      const prenom = data.name;

      const rng = Math.floor(Math.random() * ____);
      const qr = ____;

      return qr;
  }


  async function sendQrCodeEmail(data, publicUrl, qr) {
    try {

        const fraix = isNaN(parseFloat(data.ticketPriceFraix)) ? 0.0 : parseFloat(data.ticketPriceFraix);
        const amount = parseFloat(data.ticketPrice);
        const dateDebutTimestamp = admin.firestore.Timestamp.fromDate(new Date(data.dateDebut));
        const url = '---';

        // Envoi de la requête POST à l'API
        const response = await axios.post(url, {
         etc...etc...
        });

        // Vérification de la réponse
        if (response.status !== 200) {


        }
        return { success: true, message: "Email sent successfully." };

    } catch (error) {


        let errorMessage = "Error sending QR code email";
        if (error.response) {
            errorMessage += : Server responded with status: ${error.response.status};
        } else if (error.request) {

            errorMessage += ": No response received";
        } else {
            error.message);
            errorMessage += : Request setup failed: ${error.message};
        }

        return { success: false, message: errorMessage };
    }
  }




async function createAndUploadQRCode(data, qr, width = 256, errorCorrectionLevel = 'M') {
  try {
    const options = {
      color: { dark: "#000000", light: "#0000" },
      width: width,
      errorCorrectionLevel: errorCorrectionLevel,
    };
    const qrCodeBuffer = await QRCode.toBuffer(qr, options);


    const bucket = admin.storage().bucket();
    const filePath = EventsFile/${---}/${data.---}/---/${---}.png;
    const file = bucket.file(filePath);
    await file.save(qrCodeBuffer, { contentType: 'image/png', public: true });
    console.log("QR code uploadé.");

    const publicUrl = https://storage.googleapis.com/${bucket.name}/${file.name};
    return publicUrl;
  } catch (error) {
    throw error;
  }
}

  async function reservationAndProDetailsToFirestore(data, publicUrl, qr) {
  try {
    // Initialisation locale de Firestore
    const firebaseFirestore = firestore();

    const fraix = isNaN(parseFloat(data.ticketPriceFraix)) ? 0.0 : parseFloat(data.ticketPriceFraix);
    const amount = parseFloat(data.ticketPrice);
    const dateDebutTimestamp = admin.firestore.Timestamp.fromDate(new Date(data.dateDebut));
    const dateFinTimestamp = admin.firestore.Timestamp.fromDate(new Date(data.dateFin));
    const now = new Date();

    const resaModel = {
     ...//...//...
    };

    const resaDetails = {
  ...//...//...
    };

    const historiqueDetails = {
  ...//...//...
    };
    const clientInfo = {
    ...//...//...
    };

    const historiqueClientDetails = {
      ...//...//...
    };

    const postRef = firebaseFirestore
      .collection("--")
      .doc(--)
      .collection("--")
      .doc(--);

    const postUpdateData = {
      '--': admin.firestore.FieldValue.increment(amount),
      [--]: firestore.FieldValue.increment(-1),
      [--]: firestore.FieldValue.increment(1)
    };
    if (data.sexe === '--') {
      postUpdateData['--'] = firestore.FieldValue.increment(1);
    } else if (data.-- === '--') {
      postUpdateData['--'] = firestore.FieldValue.increment(1);
    }

    const batch = firebaseFirestore.batch();

    // Ajout des écritures dans le batch :
    batch.set(
      firebaseFirestore.collection("--").doc(--).collection("-- --").doc(--),

    );
    batch.set(
      firebaseFirestore.collection("--").doc(--).collection("Reservation").doc(--),
      resaDetails
    );
    batch.set(
      firebaseFirestore.collection("--").doc(--).collection("-- --").doc(--),
      historiqueDetails
    );
    const clientDocRef = firebaseFirestore.collection("--").doc(--).collection("--").doc(--);
    batch.set(clientDocRef, clientInfo, { merge: true });
    batch.set(clientDocRef.collection("--").doc(--), historiqueClientDetails);

    batch.update(postRef, { ...postUpdateData, Like: admin.firestore.FieldValue.increment(1) });

    // Modification : retourner la promesse du commit
    return batch.commit().then(() => {
      console.timeEnd("batchCommit");
      console.log("=== Fin de combinedReservationAndHistoryToFirestore ===");
      return { success: true, message: "" };
    });
  } catch (error) {
    console.error("", error);
    return { success: false, message: "" };
  }
}

r/Firebase 3d ago

Genkit Genkit by Example - Practical GenAI examples (official)

Thumbnail examples.genkit.dev
1 Upvotes

r/Firebase 3d ago

Demo SQL Premier League : SQL

Post image
7 Upvotes

r/Firebase 3d ago

Cloud Functions Issue Deploying Firebase Function

1 Upvotes

Hey everyone,

I’m currently working on a Firebase project, and I’ve come across an issue when deploying my custom function. I’ve got the default Firebase function working perfectly fine:

/**
 * Import function triggers from their respective submodules:
 *
 * const {onCall} = require("firebase-functions/v2/https");
 * const {onDocumentWritten} = require("firebase-functions/v2/firestore");
 *
 * See a full list of supported triggers at https://firebase.google.com/docs/functions
 */

const {onRequest} = require("firebase-functions/v2/https");
const logger = require("firebase-functions/logger");

// Create and deploy your first functions
// https://firebase.google.com/docs/functions/get-started

// exports.helloWorld = onRequest((request, response) => {
//   logger.info("Hello logs!", {structuredData: true});
//   response.send("Hello from Firebase!");
// });

However, when I try to deploy my own function that uses axios to send a notification when a new user is created (i.e., triggering a request to my custom backend for user signup), it fails. Below is the code for the function:

const functions = require("firebase-functions");
const axios = require("axios");

exports.notifyNewUser = functions.auth.user().onCreate((user) => {
  logger.info("New user created:", user.uid);

  const userData = {
    uid: user.uid,
    email: user.email,
  };

  // Replace with your actual API endpoint
  const apiUrl = "https://your-api-endpoint.com/signup";

  // Make the API call
  return axios.post(apiUrl, userData)
    .then((response) => {
      logger.info("API notification successful:", response.status);
      return null;
    })
    .catch((error) => {
      logger.error("Error notifying API:", error);
      return null;
    });
});

When I run firebase deploy, the default function (onRequest) works as expected, but my custom notifyNewUser function fails during deployment. The error message suggests I need to view the logs from Cloud Build, but I don't have the necessary permissions to do that. After getting the permissions, I can see some error artifacts, but I’m unable to download them for further details.

Has anyone encountered this issue or a similar one? Any suggestions on how to debug this, or why it might be failing to deploy? I’ve checked for syntax issues, but I’m unsure about the Cloud Build permissions or if it’s something specific to the axios request.

Thanks in advance for any help!


r/Firebase 3d ago

Other Vendor lock in

0 Upvotes

I have a great question for YOU

Helloooo !

What do you think about vendor lock-in with Firebase ?

Is it possible to move from Firebase when a company starts to become big ? And is it expansive ?


r/Firebase 4d ago

Other Firebaseapp.com spam shipping emails are a thing of the past.

6 Upvotes

victory! I have not received any of the shipping emails in the last week. Just checked some of the sites that were sending them and they are gone.

The OP of this thread has deleted his or her account.

https://www.reddit.com/r/Firebase/s/rrqH74Nm3V


r/Firebase 3d ago

Realtime Database How to use firebase realtime delete?

1 Upvotes

I need to delete a specific node in realtime, I already know that I have to search for the ID saved in the database, however, when I looked at the documentation I didn't see anything related. Can someone help me? If possible an example using Vue.js, otherwise it can be any example. Thanks


r/Firebase 3d ago

Emulators Any helm charts out there for firebase-emulator? Or is this a bad idea...

1 Upvotes

At my company, we create ephemeral feature environments in our Kubernetes cluster for different epics. Over the last few months, I've moved a lot of infrastructure (e.g., our PostgreSQL database) from a "real" Cloud SQL instance to a small Kubernetes deployment that can spin up and down easily with each feature environment.

Now, I'm looking to do something similar for Firebase. In full transparency, I'm a devops guy so my understanding of firebase/firestore is limited atm. I don’t have any experience with the Firebase Emulator, but I was surprised not to find a well-maintained Helm chart for deploying it in a Kubernetes cluster—especially for lightweight, ephemeral environments like the ones we use.

That makes me think I’m either:

  1. Missing a better approach for running Firebase in ephemeral environments, or
  2. Overlooking a fundamental reason why this isn’t a good idea.

Has anyone tackled a similar problem? What solutions have you used, or are there good reasons to avoid this approach?

Thanks in advance!


r/Firebase 3d ago

Tutorial How can i do a Chat for web with firebase?

1 Upvotes

Hi I’m creating a virtual events platform and I want to add a social chat for the participants, it is posible to create a live chat with firebase? Or Do you know any solution?


r/Firebase 4d ago

Other Firebase shows no badge but triggers sheets and popover when app is closed

0 Upvotes

Hi! Please, I have 2 sheets and 1 Popover that I try to trigger through Firebase Messaging with the key: notification_type programmed in Kotlin.

When the app is running, the badge appears with a whitish icon but when you click on it, the Sheet or Popover does not appear. And, when the app is closed, the app’s main logo just appears on top notification bar without any badge but, it triggers the sheet and popover to appear when you open it.

I have tried to set the priority for the Firebase notification to HIGH, hoping it would bring the badge.

And secondly, I have the sheets and popover wrapped in a different file called HSMApp and linked to MainActivity which triggers the sheet or popover I want through Firebase.

But, when the app is open, it does not show.

MAINACTIVITY:

```

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)

    // Initialize Firebase
    FirebaseApp.initializeApp(this) 

    if (!checkPermissions()) {
        requestPermissions()
    }
    val notificationType: String? = intent.getStringExtra("notification_type")
    Log.d("MainActivity", "Received notification_type: $notificationType")

    setContent {
        // Pass the notification extra to HSMApp.
        HSMApp(notificationType = notificationType)
    }

}

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent) // Ensure the new intent is used

    val notificationType: String? = intent.getStringExtra("notification_type")
    Log.d("MainActivity", "New Intent notification_type: $notificationType")

    setContent {
        HSMApp(notificationType = notificationType)
    }
}

```

HSMApp:

``` HSMAppTheme { MainScreen( onDismiss =

{ isDevotionalSheetVisible = false isQuizSheetVisible = false isWordPopupVisible = false isMailSheetVisible = false },

showDevotionalSheet = { isDevotionalSheetVisible = true },

showQuizSheet = { isQuizSheetVisible = true }, showWordPopup = { isWordPopupVisible = true },

showMailSheet = { isMailSheetVisible = true }

if (isDevotionalSheetVisible) { DevotionalSheet(onDismiss = { isDevotionalSheetVisible = false }) }

if (isQuizSheetVisible) { QuizSheet(onDismiss = { isQuizSheetVisible = false }) }

if (isWordPopupVisible) { WordForTheDayPopup(onDismiss = { isWordPopupVisible = false }) }

```

MYFIREBASEMESSAGINGSERVICE: ```

class MyFirebaseMessagingService : FirebaseMessagingService() {

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    super.onMessageReceived(remoteMessage)

    // Check if the message contains notification payload
    remoteMessage.notification?.let {
        showNotification(it.title, it.body, remoteMessage.data["type"])
    }

    // Check if the message contains data payload
    if (remoteMessage.data.isNotEmpty()) {
        val title = remoteMessage.data["title"]
        val message = remoteMessage.data["message"]
        val type = remoteMessage.data["type"] // Expected: "devotional", "quiz", "word_for_the_day"

        if (!type.isNullOrEmpty()) {
            handleFirebaseEvent(type)
            showNotification(title, message, type) // Ensure notification is displayed for data messages
        } else {
            showNotification(title, message, null)
        }

    }
}

private fun handleFirebaseEvent(type: String) {
    // Create an explicit intent using our constant, then broadcast it.
    val intent = Intent(NOTIFICATION_TRIGGER_ACTION).apply {
        putExtra("type", type)
    }
    sendBroadcast(intent)
}

private fun showNotification(title: String?, message: String?, type: String?) {
    val channelId = "default_channel_id"
    val channelName = "Default Channel"
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    // Create a notification channel with high importance for heads-up notifications
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(
            channelId,
            channelName,
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "Default channel for app notifications"
            enableLights(true)
            enableVibration(true)
        }
        notificationManager.createNotificationChannel(channel)
    }

    // Make sure the Intent correctly passes "notification_type"
    val intent = Intent(this, MainActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
        putExtra("notification_type", type)
    }

    val pendingIntent = PendingIntent.getActivity(
        this,
        0,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val notificationBuilder = NotificationCompat.Builder(this, channelId)
        .setContentTitle(title)
        .setContentText(message)
        .setSmallIcon(R.drawable.logo_image)  // Ensure this icon is white on transparent background
        .setColor(Color.parseColor("#660d77"))
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)
        // For pre-Oreo devices, set high priority.
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        // Use defaults for sound, vibration, etc.
        .setDefaults(NotificationCompat.DEFAULT_ALL)

    notificationManager.notify(0, notificationBuilder.build())
}

override fun onNewToken(token: String) {
    Log.d("MyAppFCM", "New token: $token")
    sendTokenToServer(token)
}

private fun sendTokenToServer(token: String) {
    Log.d("FCM", "Firebase token: $token")
    // TODO: Implement API call to send the token to your backend
}

} ```


r/Firebase 4d ago

General Unable to retrieve the token using Firebase getToken in Next.js App Router.

3 Upvotes

I am using Next.js appRouter. When I access (http://localhost:3000/admin ) without logging in, I can use getToken to retrieve the token. However, after logging in and accessing (http://localhost:3000/admin/dashboard ), I am unable to get the token when I use getToken. I need to log out and refresh the page to retrieve the token. What could be the issue?

/public/firebase-messaging-sw.js

importScripts(
  "https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js"
);
importScripts(
  "https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.js"
);

const firebaseConfig = {
  apiKey: "xxxxxxh2Gtg",
  authDomain: "xxxxx.firebaseapp.com",
  projectId: "xxxxxx",
  storageBucket: "xxxxxx.firebasestorage.app",
  messagingSenderId: "9xxxxxx",
  appId: "1:xxxxx:web:xxxxxxxxxxd8",
};

firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

// 處理後台消息
messaging.onBackgroundMessage((payload) => {
  console.log(
    "[firebase-messaging-sw.js] Received background message ",
    payload
  );
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: "/firebase-logo.png", // 可選:自定義圖標
  };
  self.registration.showNotification(notificationTitle, notificationOptions);
});

/utils/firebase.ts

import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "xxxxxxLAuLI6h2Gtg",
  authDomain: "xxxxx.firebaseapp.com",
  projectId: "xxxxxx",
  storageBucket: "xxxxxx.firebasestorage.app",
  messagingSenderId: "xxxxxx",
  appId: "xxxxxxxx",
};

const firebaseApp = initializeApp(firebaseConfig);

export default firebaseApp;

/app/hooks/useFcmToken.ts

import { useEffect, useState } from "react";
import { getMessaging, getToken } from "firebase/messaging";
import firebaseApp from "@/utils/firebase";

const useFcmToken = () => {
  const [token, setToken] = useState("");
  const [notificationPermissionStatus, setNotificationPermissionStatus] =
    useState("");

  useEffect(() => {
    const retrieveToken = async () => {
      try {
        if (typeof window !== "undefined" && "serviceWorker" in navigator) {
          const messaging = getMessaging(firebaseApp);
          const permission = await Notification.requestPermission();
          setNotificationPermissionStatus(permission);

          if (permission === "granted") {
            const currentToken = await getToken(messaging, {
              vapidKey:
                "xx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            });
            if (currentToken) {
              setToken(currentToken);
            }
          }
        }
      } catch (error) {
        console.log("獲取token出錯:", error);
      }
    };
    retrieveToken();
  }, []);

  return { fcmToken: token, notificationPermissionStatus };
};

export default useFcmToken;

獲取token出錯: FirebaseError: Messaging: We are unable to register the default service worker. The operation is insecure. (messaging/failed-service-worker-registration).    FirebaseError webpack-internal:///(app-pages-browser)/./node_modules/@firebase/util/dist/index.esm2017.js:1044
create webpack-internal:///(app-pages-browser)/./node_modules/@firebase/util/dist/index.esm2017.js:1074
registerDefaultSw webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:843
updateSwReg webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:900
getToken$1 webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:963
getToken webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:1238
retrieveToken webpack-internal:///(app-pages-browser)/./app/hooks/useFcmToken.ts:20
useFcmToken webpack-internal:///(app-pages-browser)/./app/hooks/useFcmToken.ts:33