Testing Firebase Cloud Messaging Without Console Access

Sahil AhmedSahil Ahmed
5 min read

Firebase Cloud Messaging (FCM) is a popular service for sending notifications to mobile and web applications. However, what if you need to test FCM functionality without having access to the Firebase console or the account's email and password? In this article, we'll explore a method to set up a Node.js application for testing FCM, using only a service account credential file.

The Node.js Application

Let's start by looking at the Node.js application that will send FCM messages:

import { initializeApp, applicationDefault } from "firebase-admin/app";
import { getMessaging } from "firebase-admin/messaging";
import express, { json } from "express";
import cors from "cors";

process.env.GOOGLE_APPLICATION_CREDENTIALS;

const app = express();
app.use(express.json());
app.use(cors({ origin: "*" }));
app.use(cors({ methods: ["GET", "POST", "DELETE", "UPDATE", "PUT", "PATCH"] }));
app.use(function (req, res, next) {
  res.setHeader("Content-Type", "application/json");
  next();
});

initializeApp({
  credential: applicationDefault(),
  projectId: "your-project-id",
});

app.post("/send", function (req, res) {
  const receivedToken = req.body.fcmToken;
  const message = {
    notification: {
      title: "Notif",
      body: "This is a Test Notification",
    },
    token: receivedToken,
  };

  getMessaging()
    .send(message)
    .then((response) => {
      res.status(200).json({
        message: "Successfully sent message",
        token: receivedToken,
      });
      console.log("Successfully sent message:", response);
    })
    .catch((error) => {
      res.status(400);
      res.send(error);
      console.log("Error sending message:", error);
    });
});

app.listen(3000, function () {
  console.log("Server started on port 3000");
});

This application sets up an Express server with a single POST endpoint /send. When a request is made to this endpoint with an FCM token in the body, it sends a test notification to that token.

Technical Details

  1. Firebase Admin SDK: The application uses the Firebase Admin SDK (firebase-admin) to initialize the app and send messages. This SDK allows server-side operations without needing the Firebase console.

  2. Service Account Credentials: The application uses applicationDefault() to load credentials. This method looks for the GOOGLE_APPLICATION_CREDENTIALS environment variable, which should point to a JSON file containing service account credentials.

  3. Express Server: The application sets up a simple Express server to handle HTTP requests. It uses CORS middleware to allow cross-origin requests, which is useful for testing.

  4. FCM Message Structure: The message object includes a notification field with title and body, and a token field for the FCM token of the target device.

Setting Up the Environment

To run this application, you need to set up a few things:

  1. Create a .env file with the following content:
GOOGLE_APPLICATION_CREDENTIALS=credentials.json
PORT=3000
  1. Create a credentials.json file with your service account credentials. Here's a template (remember to replace with your actual credentials):
{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "your-private-key-id",
  "private_key": "-----BEGIN PRIVATE KEY-----\nYour Private Key\n-----END PRIVATE KEY-----\n",
  "client_email": "your-client-email@your-project-id.iam.gserviceaccount.com",
  "client_id": "your-client-id",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-service-account-email"
}
  1. Update your package.json file to include the following scripts:
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "send": "curl -X POST http://localhost:3000/send",
  "start": "node index.js"
},

These scripts allow you to easily start your server (npm start) and send a test message (npm run send).

  1. If you plan to upload your project to a version control system like GitHub, create a .gitignore file and add the following lines:
node_modules/
.env
credentials.json

This prevents sensitive information and unnecessary files from being uploaded to your repository.

How to Use

  1. Install the necessary dependencies by running npm install in your project directory.

  2. Start the Node.js server by running npm start.

  3. Send a POST request to http://localhost:3000/send with a JSON body containing an fcmToken field. You can use the provided npm run send script or a tool like Postman for this.

  4. The server will attempt to send a test notification to the provided token and return the result.

[... Rest of the content remains the same ...]

Security Considerations

  1. Credential Protection: The credentials.json file contains sensitive information. Never commit this file to version control. Use environment variables or secure secret management systems in production.

  2. CORS Configuration: The current CORS setup allows requests from any origin (*). In a production environment, you should restrict this to specific trusted origins.

  3. Error Handling: The current implementation sends detailed error information back to the client. In production, you might want to log errors server-side and send more generic error messages to clients.

Merits and Use Cases

This approach has several merits:

  1. Testing Without Console Access: It allows developers to test FCM functionality without needing direct access to the Firebase console.

  2. CI/CD Integration: This setup can be easily integrated into CI/CD pipelines for automated testing of notification features.

  3. Separated Concerns: By using a service account, you can create a testing environment that's separate from your production Firebase setup.

  4. API Development: This setup provides a foundation for building a notification API that other services could use.

  5. Debugging: It allows for easy debugging of FCM issues by providing direct control over the message sending process.

However, it's important to note that this approach should primarily be used for testing and development. In a production environment, you would typically want more robust error handling, security measures, and possibly rate limiting to prevent abuse.

Conclusion

While having full access to the Firebase console is ideal, this method provides a valuable alternative for testing FCM functionality. It's particularly useful in scenarios where console access is restricted or when you need to automate FCM testing in your development workflow.

Remember to always handle credentials securely and to transition to more robust setups when moving to production environments.

0
Subscribe to my newsletter

Read articles from Sahil Ahmed directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sahil Ahmed
Sahil Ahmed

I'm Sahil Ahmed, an experienced software engineer who wants to be a digital polymath. My journey in software development is driven by a curiosity to create efficient, user-centric solutions for real-world problems across web and mobile platforms while writing clean code. I also love to read classic literature and play football.