Fixing “Service Account Must Be an Object” Error When Initializing Firebase in NestJS (Updated with ES Module Imports)
When working with Firebase in a NestJS project, many developers encounter the common error:
Error: Service account must be an object.
This error typically occurs during Firebase initialization when the service account is imported incorrectly. In this updated article, I’ll show you how to fix this error using import * as serviceAccount
instead of require
.
Why the Error Occurs
The error happens because Firebase expects the service account to be a plain JavaScript object. If you use require
, TypeScript may interpret the import incorrectly, causing Firebase to receive an invalid service account configuration.
The Correct Fix: Use import * as serviceAccount
Step 1: Ensure Correct Service Account File Setup
Make sure your Firebase service account file (serviceAccountKey.json
) is stored securely in the root of your project or in a config
directory. Avoid committing this file to source control.
Step 2: Install Firebase Admin SDK
npm install firebase-admin
Step 3: Update Firebase Initialization in NestJS
Use the following code to initialize Firebase:
// notification.service.ts
import { Injectable } from '@nestjs/common';
import * as admin from 'firebase-admin';
import * as serviceAccount from '../config/serviceAccountKey.json';
@Injectable()
export class NotificationService {
constructor() {
// Initialize Firebase Admin
admin.initializeApp({
credential: admin.credential.cert(serviceAccount as admin.ServiceAccount),
});
console.log('Firebase initialized successfully.');
}
async sendNotification(token: string, title: string, body: string) {
const message = {
notification: {
title,
body,
},
token,
};
try {
const response = await admin.messaging().send(message);
console.log('Successfully sent message:', response);
} catch (error) {
console.error('Error sending message:', error);
}
}
}
Why This Works
The critical fix is replacing require
with:
import * as serviceAccount from '../config/serviceAccountKey.json';
TypeScript interprets this correctly, ensuring the service account is passed as a plain JavaScript object.
Best Practices
- Environment Management: Use environment variables to manage sensitive keys securely.
- Git Ignore: Add the service account file to
.gitignore
to prevent it from being pushed to source control. - CI/CD Secrets Management: Use secret management tools like AWS Secrets Manager, Google Secret Manager, or HashiCorp Vault.
Conclusion
By using import * as serviceAccount
, you ensure the correct initialization of Firebase in your NestJS project. This approach prevents the dreaded "Service account must be an object" error and keeps your project running smoothly.
Let me know if you’d like further customization of this article! ๐