nestjs-firebase-admin 0.3.5 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './modules/admin/admin.module';
2
2
  export * from './modules/admin/admin.service';
3
3
  export * from './modules/admin/database.service';
4
+ export * from './modules/admin/messaging.service';
4
5
  export * from './modules/admin/interfaces';
5
6
  export * from './modules/admin/types';
package/dist/index.js CHANGED
@@ -17,5 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./modules/admin/admin.module"), exports);
18
18
  __exportStar(require("./modules/admin/admin.service"), exports);
19
19
  __exportStar(require("./modules/admin/database.service"), exports);
20
+ __exportStar(require("./modules/admin/messaging.service"), exports);
20
21
  __exportStar(require("./modules/admin/interfaces"), exports);
21
22
  __exportStar(require("./modules/admin/types"), exports);
@@ -1,3 +1,4 @@
1
1
  export declare const FIREBASE_ADMIN_INSTANCE_TOKEN = "FIREBASE_ADMIN_INSTANCE_TOKEN";
2
+ export declare const FIREBASE_ADMIN_APP = "FIREBASE_ADMIN_APP";
2
3
  export declare const ADMIN_MODULE_ID = "ADMIN_MODULE_ID";
3
4
  export declare const ADMIN_MODULE_OPTIONS = "ADMIN_MODULE_OPTIONS";
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ADMIN_MODULE_OPTIONS = exports.ADMIN_MODULE_ID = exports.FIREBASE_ADMIN_INSTANCE_TOKEN = void 0;
3
+ exports.ADMIN_MODULE_OPTIONS = exports.ADMIN_MODULE_ID = exports.FIREBASE_ADMIN_APP = exports.FIREBASE_ADMIN_INSTANCE_TOKEN = void 0;
4
4
  exports.FIREBASE_ADMIN_INSTANCE_TOKEN = 'FIREBASE_ADMIN_INSTANCE_TOKEN';
5
+ exports.FIREBASE_ADMIN_APP = 'FIREBASE_ADMIN_APP';
5
6
  exports.ADMIN_MODULE_ID = 'ADMIN_MODULE_ID';
6
7
  exports.ADMIN_MODULE_OPTIONS = 'ADMIN_MODULE_OPTIONS';
@@ -26,18 +26,22 @@ const firebase_admin_1 = __importDefault(require("firebase-admin"));
26
26
  const admin_constants_1 = require("./admin.constants");
27
27
  const admin_service_1 = require("./admin.service");
28
28
  const database_service_1 = require("./database.service");
29
+ const messaging_service_1 = require("./messaging.service");
29
30
  let AdminModule = AdminModule_1 = class AdminModule {
30
31
  static register(options) {
31
32
  const firebaseApp = firebase_admin_1.default.initializeApp(Object.assign(Object.assign({}, options), { credential: firebase_admin_1.default.credential.cert(options.credential) }));
32
33
  return {
33
34
  module: AdminModule_1,
34
35
  providers: [
36
+ admin_service_1.AdminService,
37
+ database_service_1.DatabaseService,
38
+ messaging_service_1.MessagingService,
35
39
  {
36
40
  provide: admin_constants_1.FIREBASE_ADMIN_INSTANCE_TOKEN,
37
41
  useValue: options,
38
42
  },
39
43
  {
40
- provide: 'FIREBASE_ADMIN_APP',
44
+ provide: admin_constants_1.FIREBASE_ADMIN_APP,
41
45
  useValue: firebaseApp,
42
46
  },
43
47
  {
@@ -45,10 +49,25 @@ let AdminModule = AdminModule_1 = class AdminModule {
45
49
  useValue: (0, random_string_generator_util_1.randomStringGenerator)(),
46
50
  },
47
51
  ],
52
+ exports: [
53
+ admin_service_1.AdminService,
54
+ database_service_1.DatabaseService,
55
+ messaging_service_1.MessagingService,
56
+ admin_constants_1.FIREBASE_ADMIN_INSTANCE_TOKEN,
57
+ admin_constants_1.FIREBASE_ADMIN_APP,
58
+ ],
48
59
  };
49
60
  }
50
61
  static registerAsync(options) {
51
- const providers = [];
62
+ const providers = [
63
+ admin_service_1.AdminService,
64
+ database_service_1.DatabaseService,
65
+ messaging_service_1.MessagingService,
66
+ {
67
+ provide: admin_constants_1.ADMIN_MODULE_ID,
68
+ useValue: (0, random_string_generator_util_1.randomStringGenerator)(),
69
+ },
70
+ ];
52
71
  if (options.useFactory) {
53
72
  const factory = options.useFactory;
54
73
  providers.push({
@@ -57,7 +76,7 @@ let AdminModule = AdminModule_1 = class AdminModule {
57
76
  inject: options.inject || [],
58
77
  });
59
78
  providers.push({
60
- provide: 'FIREBASE_ADMIN_APP',
79
+ provide: admin_constants_1.FIREBASE_ADMIN_APP,
61
80
  useFactory: (...args) => __awaiter(this, void 0, void 0, function* () {
62
81
  const config = yield factory(...args);
63
82
  return firebase_admin_1.default.initializeApp(Object.assign(Object.assign({}, config), { credential: firebase_admin_1.default.credential.cert(config.credential) }));
@@ -75,7 +94,7 @@ let AdminModule = AdminModule_1 = class AdminModule {
75
94
  inject: [options.useExisting],
76
95
  });
77
96
  providers.push({
78
- provide: 'FIREBASE_ADMIN_APP',
97
+ provide: admin_constants_1.FIREBASE_ADMIN_APP,
79
98
  useFactory: (optionsFactory) => __awaiter(this, void 0, void 0, function* () {
80
99
  const config = yield optionsFactory.createAdminOptions();
81
100
  return firebase_admin_1.default.initializeApp(Object.assign(Object.assign({}, config), { credential: firebase_admin_1.default.credential.cert(config.credential) }));
@@ -97,7 +116,7 @@ let AdminModule = AdminModule_1 = class AdminModule {
97
116
  inject: [options.useClass],
98
117
  });
99
118
  providers.push({
100
- provide: 'FIREBASE_ADMIN_APP',
119
+ provide: admin_constants_1.FIREBASE_ADMIN_APP,
101
120
  useFactory: (optionsFactory) => __awaiter(this, void 0, void 0, function* () {
102
121
  const config = yield optionsFactory.createAdminOptions();
103
122
  return firebase_admin_1.default.initializeApp(Object.assign(Object.assign({}, config), { credential: firebase_admin_1.default.credential.cert(config.credential) }));
@@ -112,14 +131,28 @@ let AdminModule = AdminModule_1 = class AdminModule {
112
131
  module: AdminModule_1,
113
132
  imports: options.imports,
114
133
  providers,
115
- exports: [admin_service_1.AdminService],
134
+ exports: [
135
+ admin_service_1.AdminService,
136
+ database_service_1.DatabaseService,
137
+ messaging_service_1.MessagingService,
138
+ admin_constants_1.FIREBASE_ADMIN_INSTANCE_TOKEN,
139
+ admin_constants_1.FIREBASE_ADMIN_APP,
140
+ ],
116
141
  };
117
142
  }
118
143
  };
119
144
  exports.AdminModule = AdminModule;
120
145
  exports.AdminModule = AdminModule = AdminModule_1 = __decorate([
121
146
  (0, common_1.Module)({
122
- providers: [admin_service_1.AdminService, database_service_1.DatabaseService],
123
- exports: [admin_service_1.AdminService, database_service_1.DatabaseService],
147
+ providers: [
148
+ admin_service_1.AdminService,
149
+ database_service_1.DatabaseService,
150
+ messaging_service_1.MessagingService,
151
+ {
152
+ provide: admin_constants_1.ADMIN_MODULE_ID,
153
+ useValue: (0, random_string_generator_util_1.randomStringGenerator)(),
154
+ },
155
+ ],
156
+ exports: [admin_service_1.AdminService, database_service_1.DatabaseService, messaging_service_1.MessagingService],
124
157
  })
125
158
  ], AdminModule);
@@ -0,0 +1,105 @@
1
+ import { App } from 'firebase-admin/app';
2
+ import { Messaging, Message, MulticastMessage, TopicMessage } from 'firebase-admin/messaging';
3
+ interface AppWithMessaging extends App {
4
+ messaging(): Messaging;
5
+ }
6
+ export declare class MessagingService {
7
+ private readonly app;
8
+ private readonly messaging;
9
+ constructor(app: AppWithMessaging);
10
+ sendToDevice(token: string, payload: Partial<Message>): Promise<string>;
11
+ sendToDevices(tokens: string[], payload: Partial<MulticastMessage>): Promise<MessagingBatchResponse>;
12
+ sendToTopic(topic: string, payload: Partial<TopicMessage>): Promise<string>;
13
+ subscribeToTopic(tokens: string[], topic: string): Promise<MessagingTopicManagementResponse>;
14
+ unsubscribeFromTopic(tokens: string[], topic: string): Promise<MessagingTopicManagementResponse>;
15
+ }
16
+ export interface MessagingPayload {
17
+ notification?: {
18
+ title?: string;
19
+ body?: string;
20
+ imageUrl?: string;
21
+ };
22
+ data?: {
23
+ [key: string]: string;
24
+ };
25
+ android?: {
26
+ priority?: 'high' | 'normal';
27
+ ttl?: number;
28
+ notification?: {
29
+ channelId?: string;
30
+ clickAction?: string;
31
+ color?: string;
32
+ icon?: string;
33
+ sound?: string;
34
+ tag?: string;
35
+ title?: string;
36
+ body?: string;
37
+ };
38
+ };
39
+ apns?: {
40
+ payload?: {
41
+ aps?: {
42
+ alert?: {
43
+ title?: string;
44
+ body?: string;
45
+ };
46
+ sound?: string;
47
+ badge?: number;
48
+ };
49
+ };
50
+ headers?: {
51
+ [key: string]: string;
52
+ };
53
+ };
54
+ webpush?: {
55
+ headers?: {
56
+ [key: string]: string;
57
+ };
58
+ notification?: {
59
+ title?: string;
60
+ body?: string;
61
+ icon?: string;
62
+ badge?: string;
63
+ data?: {
64
+ [key: string]: string;
65
+ };
66
+ actions?: Array<{
67
+ action: string;
68
+ title: string;
69
+ icon?: string;
70
+ }>;
71
+ };
72
+ };
73
+ }
74
+ export type MessagingMessage = {
75
+ token: string;
76
+ } & MessagingPayload;
77
+ export type MessagingMulticastMessage = {
78
+ tokens: string[];
79
+ } & MessagingPayload;
80
+ export type MessagingTopicMessage = {
81
+ topic: string;
82
+ } & MessagingPayload;
83
+ export type MessagingBatchResponse = {
84
+ successCount: number;
85
+ failureCount: number;
86
+ responses: Array<{
87
+ messageId?: string;
88
+ error?: {
89
+ code: string;
90
+ message: string;
91
+ };
92
+ }>;
93
+ };
94
+ export type MessagingTopicManagementResponse = {
95
+ successCount: number;
96
+ failureCount: number;
97
+ errors: Array<{
98
+ index: number;
99
+ error: {
100
+ code: string;
101
+ message: string;
102
+ };
103
+ }>;
104
+ };
105
+ export {};
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.MessagingService = void 0;
25
+ const common_1 = require("@nestjs/common");
26
+ const admin_constants_1 = require("./admin.constants");
27
+ let MessagingService = class MessagingService {
28
+ constructor(app) {
29
+ this.app = app;
30
+ this.messaging = this.app.messaging();
31
+ }
32
+ sendToDevice(token, payload) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const message = Object.assign({ token }, payload);
35
+ const response = yield this.messaging.send(message);
36
+ return response;
37
+ });
38
+ }
39
+ sendToDevices(tokens, payload) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ const message = Object.assign({ tokens }, payload);
42
+ const response = yield this.messaging.sendMulticast(message);
43
+ return response;
44
+ });
45
+ }
46
+ sendToTopic(topic, payload) {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const message = Object.assign({ topic }, payload);
49
+ const response = yield this.messaging.send(message);
50
+ return response;
51
+ });
52
+ }
53
+ subscribeToTopic(tokens, topic) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const response = yield this.messaging.subscribeToTopic(tokens, topic);
56
+ return response;
57
+ });
58
+ }
59
+ unsubscribeFromTopic(tokens, topic) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ const response = yield this.messaging.unsubscribeFromTopic(tokens, topic);
62
+ return response;
63
+ });
64
+ }
65
+ };
66
+ exports.MessagingService = MessagingService;
67
+ exports.MessagingService = MessagingService = __decorate([
68
+ (0, common_1.Injectable)(),
69
+ __param(0, (0, common_1.Inject)(admin_constants_1.FIREBASE_ADMIN_APP)),
70
+ __metadata("design:paramtypes", [Object])
71
+ ], MessagingService);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const testing_1 = require("@nestjs/testing");
13
+ const messaging_service_1 = require("./messaging.service");
14
+ const admin_constants_1 = require("./admin.constants");
15
+ jest.mock('firebase-admin/messaging', () => {
16
+ return {
17
+ Messaging: jest.fn().mockImplementation(() => ({
18
+ send: jest.fn().mockResolvedValue('message-id'),
19
+ sendMulticast: jest.fn().mockResolvedValue({
20
+ successCount: 1,
21
+ failureCount: 0,
22
+ responses: [{ messageId: 'message-id' }],
23
+ }),
24
+ subscribeToTopic: jest.fn().mockResolvedValue({
25
+ successCount: 1,
26
+ failureCount: 0,
27
+ errors: [],
28
+ }),
29
+ unsubscribeFromTopic: jest.fn().mockResolvedValue({
30
+ successCount: 1,
31
+ failureCount: 0,
32
+ errors: [],
33
+ }),
34
+ })),
35
+ };
36
+ });
37
+ describe('MessagingService', () => {
38
+ let service;
39
+ let mockMessaging;
40
+ beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
41
+ const mockApp = {
42
+ messaging: jest.fn().mockReturnValue({
43
+ send: jest.fn().mockResolvedValue('message-id'),
44
+ sendMulticast: jest.fn().mockResolvedValue({
45
+ successCount: 1,
46
+ failureCount: 0,
47
+ responses: [{ messageId: 'message-id' }],
48
+ }),
49
+ subscribeToTopic: jest.fn().mockResolvedValue({
50
+ successCount: 1,
51
+ failureCount: 0,
52
+ errors: [],
53
+ }),
54
+ unsubscribeFromTopic: jest.fn().mockResolvedValue({
55
+ successCount: 1,
56
+ failureCount: 0,
57
+ errors: [],
58
+ }),
59
+ }),
60
+ };
61
+ const module = yield testing_1.Test.createTestingModule({
62
+ providers: [
63
+ messaging_service_1.MessagingService,
64
+ {
65
+ provide: admin_constants_1.FIREBASE_ADMIN_APP,
66
+ useValue: mockApp,
67
+ },
68
+ ],
69
+ }).compile();
70
+ service = module.get(messaging_service_1.MessagingService);
71
+ mockMessaging = mockApp.messaging();
72
+ }));
73
+ it('should be defined', () => {
74
+ expect(service).toBeDefined();
75
+ });
76
+ describe('sendToDevice', () => {
77
+ it('should send a message to a single device', () => __awaiter(void 0, void 0, void 0, function* () {
78
+ const token = 'device-token';
79
+ const payload = {
80
+ notification: {
81
+ title: 'Test Title',
82
+ body: 'Test Body',
83
+ },
84
+ };
85
+ const result = yield service.sendToDevice(token, payload);
86
+ expect(result).toBe('message-id');
87
+ expect(mockMessaging.send).toHaveBeenCalledWith(Object.assign({ token }, payload));
88
+ }));
89
+ });
90
+ describe('sendToDevices', () => {
91
+ it('should send a message to multiple devices', () => __awaiter(void 0, void 0, void 0, function* () {
92
+ const tokens = ['token1', 'token2'];
93
+ const payload = {
94
+ notification: {
95
+ title: 'Test Title',
96
+ body: 'Test Body',
97
+ },
98
+ };
99
+ const result = yield service.sendToDevices(tokens, payload);
100
+ expect(result).toEqual({
101
+ successCount: 1,
102
+ failureCount: 0,
103
+ responses: [{ messageId: 'message-id' }],
104
+ });
105
+ expect(mockMessaging.sendMulticast).toHaveBeenCalledWith(Object.assign({ tokens }, payload));
106
+ }));
107
+ });
108
+ describe('sendToTopic', () => {
109
+ it('should send a message to a topic', () => __awaiter(void 0, void 0, void 0, function* () {
110
+ const topic = 'test-topic';
111
+ const payload = {
112
+ notification: {
113
+ title: 'Test Title',
114
+ body: 'Test Body',
115
+ },
116
+ };
117
+ const result = yield service.sendToTopic(topic, payload);
118
+ expect(result).toBe('message-id');
119
+ expect(mockMessaging.send).toHaveBeenCalledWith(Object.assign({ topic }, payload));
120
+ }));
121
+ });
122
+ describe('subscribeToTopic', () => {
123
+ it('should subscribe devices to a topic', () => __awaiter(void 0, void 0, void 0, function* () {
124
+ const tokens = ['token1', 'token2'];
125
+ const topic = 'test-topic';
126
+ const result = yield service.subscribeToTopic(tokens, topic);
127
+ expect(result).toEqual({
128
+ successCount: 1,
129
+ failureCount: 0,
130
+ errors: [],
131
+ });
132
+ expect(mockMessaging.subscribeToTopic).toHaveBeenCalledWith(tokens, topic);
133
+ }));
134
+ });
135
+ describe('unsubscribeFromTopic', () => {
136
+ it('should unsubscribe devices from a topic', () => __awaiter(void 0, void 0, void 0, function* () {
137
+ const tokens = ['token1', 'token2'];
138
+ const topic = 'test-topic';
139
+ const result = yield service.unsubscribeFromTopic(tokens, topic);
140
+ expect(result).toEqual({
141
+ successCount: 1,
142
+ failureCount: 0,
143
+ errors: [],
144
+ });
145
+ expect(mockMessaging.unsubscribeFromTopic).toHaveBeenCalledWith(tokens, topic);
146
+ }));
147
+ });
148
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-firebase-admin",
3
- "version": "0.3.5",
3
+ "version": "0.4.5",
4
4
  "description": "Firebase Admin SDK for Nestjs",
5
5
  "author": "Hebert Cisco",
6
6
  "license": "MIT",