@prmichaelsen/firebase-admin-sdk-v8 2.5.2 → 2.6.0
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/.claude/settings.local.json +10 -1
- package/CHANGELOG.md +19 -0
- package/dist/index.d.mts +148 -1
- package/dist/index.d.ts +148 -1
- package/dist/index.js +96 -0
- package/dist/index.mjs +91 -0
- package/package.json +1 -1
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
"Bash(./agent/scripts/acp.version-check-for-updates.sh:*)",
|
|
5
5
|
"Bash(test:*)",
|
|
6
6
|
"Bash(ls:*)",
|
|
7
|
-
"Bash(git add:*)"
|
|
7
|
+
"Bash(git add:*)",
|
|
8
|
+
"Bash(grep:*)",
|
|
9
|
+
"Bash(npm test:*)",
|
|
10
|
+
"Bash(npm run:*)",
|
|
11
|
+
"Bash(bash:*)",
|
|
12
|
+
"Bash(npx jest:*)",
|
|
13
|
+
"WebFetch(domain:agentbase.me)",
|
|
14
|
+
"WebSearch",
|
|
15
|
+
"WebFetch(domain:firebase.google.com)",
|
|
16
|
+
"WebFetch(domain:developers.google.com)"
|
|
8
17
|
]
|
|
9
18
|
}
|
|
10
19
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.6.0] - 2026-03-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Firebase Cloud Messaging (FCM)**: Server-side push notification support via FCM HTTP v1 API
|
|
12
|
+
- `sendMessage()` - Send notifications to devices, topics, or conditions
|
|
13
|
+
- `subscribeToTopic()` - Subscribe up to 1000 device tokens to a topic
|
|
14
|
+
- `unsubscribeFromTopic()` - Unsubscribe device tokens from a topic
|
|
15
|
+
- Full TypeScript types for Message, Notification, AndroidConfig, WebpushConfig, ApnsConfig
|
|
16
|
+
- Platform-specific configuration support (Android, Web, iOS)
|
|
17
|
+
- Data-only messages and notification+data payloads
|
|
18
|
+
- Topic name normalization (auto-prefixes `/topics/` when missing)
|
|
19
|
+
- 29 comprehensive unit tests
|
|
20
|
+
- New module: `src/messaging/` (client, types, index)
|
|
21
|
+
- New exported types: `Message`, `FcmNotification`, `AndroidConfig`, `AndroidNotification`, `WebpushConfig`, `ApnsConfig`, `FcmOptions`, `SendResponse`, `TopicManagementResponse`, `TopicManagementError`
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Total unit tests increased from 469 to 498 (+29 tests)
|
|
25
|
+
- Total test suites increased from 16 to 17
|
|
26
|
+
|
|
8
27
|
## [2.5.2] - 2026-03-03
|
|
9
28
|
|
|
10
29
|
### Fixed
|
package/dist/index.d.mts
CHANGED
|
@@ -1006,6 +1006,153 @@ interface ResumableUploadOptions extends UploadOptions {
|
|
|
1006
1006
|
*/
|
|
1007
1007
|
declare function uploadFileResumable(path: string, data: ArrayBuffer | Uint8Array | Blob | ReadableStream<Uint8Array>, contentType: string, options?: ResumableUploadOptions): Promise<FileMetadata>;
|
|
1008
1008
|
|
|
1009
|
+
/**
|
|
1010
|
+
* Firebase Cloud Messaging (FCM) Types
|
|
1011
|
+
* Based on FCM HTTP v1 API specification
|
|
1012
|
+
*/
|
|
1013
|
+
interface Message {
|
|
1014
|
+
/** Device registration token (mutually exclusive with topic/condition) */
|
|
1015
|
+
token?: string;
|
|
1016
|
+
/** Topic name (mutually exclusive with token/condition) */
|
|
1017
|
+
topic?: string;
|
|
1018
|
+
/** Condition expression for topic combinations (mutually exclusive with token/topic) */
|
|
1019
|
+
condition?: string;
|
|
1020
|
+
/** Basic notification payload displayed on all platforms */
|
|
1021
|
+
notification?: Notification;
|
|
1022
|
+
/** Custom key-value data payload */
|
|
1023
|
+
data?: Record<string, string>;
|
|
1024
|
+
/** Android-specific configuration */
|
|
1025
|
+
android?: AndroidConfig;
|
|
1026
|
+
/** Web push protocol configuration */
|
|
1027
|
+
webpush?: WebpushConfig;
|
|
1028
|
+
/** Apple Push Notification Service configuration */
|
|
1029
|
+
apns?: ApnsConfig;
|
|
1030
|
+
/** FCM-specific options */
|
|
1031
|
+
fcm_options?: FcmOptions;
|
|
1032
|
+
}
|
|
1033
|
+
interface Notification {
|
|
1034
|
+
title?: string;
|
|
1035
|
+
body?: string;
|
|
1036
|
+
image?: string;
|
|
1037
|
+
}
|
|
1038
|
+
interface AndroidConfig {
|
|
1039
|
+
collapse_key?: string;
|
|
1040
|
+
priority?: 'high' | 'normal';
|
|
1041
|
+
ttl?: string;
|
|
1042
|
+
restricted_package_name?: string;
|
|
1043
|
+
data?: Record<string, string>;
|
|
1044
|
+
notification?: AndroidNotification;
|
|
1045
|
+
fcm_options?: AndroidFcmOptions;
|
|
1046
|
+
direct_boot_ok?: boolean;
|
|
1047
|
+
}
|
|
1048
|
+
interface AndroidNotification {
|
|
1049
|
+
title?: string;
|
|
1050
|
+
body?: string;
|
|
1051
|
+
icon?: string;
|
|
1052
|
+
color?: string;
|
|
1053
|
+
sound?: string;
|
|
1054
|
+
tag?: string;
|
|
1055
|
+
click_action?: string;
|
|
1056
|
+
body_loc_key?: string;
|
|
1057
|
+
body_loc_args?: string[];
|
|
1058
|
+
title_loc_key?: string;
|
|
1059
|
+
title_loc_args?: string[];
|
|
1060
|
+
channel_id?: string;
|
|
1061
|
+
ticker?: string;
|
|
1062
|
+
sticky?: boolean;
|
|
1063
|
+
event_time?: string;
|
|
1064
|
+
local_only?: boolean;
|
|
1065
|
+
notification_priority?: AndroidNotificationPriority;
|
|
1066
|
+
default_sound?: boolean;
|
|
1067
|
+
default_vibrate_timings?: boolean;
|
|
1068
|
+
default_light_settings?: boolean;
|
|
1069
|
+
vibrate_timings?: string[];
|
|
1070
|
+
visibility?: 'VISIBILITY_UNSPECIFIED' | 'PRIVATE' | 'PUBLIC' | 'SECRET';
|
|
1071
|
+
notification_count?: number;
|
|
1072
|
+
light_settings?: LightSettings;
|
|
1073
|
+
image?: string;
|
|
1074
|
+
}
|
|
1075
|
+
type AndroidNotificationPriority = 'PRIORITY_UNSPECIFIED' | 'PRIORITY_MIN' | 'PRIORITY_LOW' | 'PRIORITY_DEFAULT' | 'PRIORITY_HIGH' | 'PRIORITY_MAX';
|
|
1076
|
+
interface LightSettings {
|
|
1077
|
+
color: {
|
|
1078
|
+
red: number;
|
|
1079
|
+
green: number;
|
|
1080
|
+
blue: number;
|
|
1081
|
+
alpha: number;
|
|
1082
|
+
};
|
|
1083
|
+
light_on_duration: string;
|
|
1084
|
+
light_off_duration: string;
|
|
1085
|
+
}
|
|
1086
|
+
interface AndroidFcmOptions {
|
|
1087
|
+
analytics_label?: string;
|
|
1088
|
+
}
|
|
1089
|
+
interface WebpushConfig {
|
|
1090
|
+
headers?: Record<string, string>;
|
|
1091
|
+
data?: Record<string, string>;
|
|
1092
|
+
notification?: Record<string, unknown>;
|
|
1093
|
+
fcm_options?: WebpushFcmOptions;
|
|
1094
|
+
}
|
|
1095
|
+
interface WebpushFcmOptions {
|
|
1096
|
+
link?: string;
|
|
1097
|
+
analytics_label?: string;
|
|
1098
|
+
}
|
|
1099
|
+
interface ApnsConfig {
|
|
1100
|
+
headers?: Record<string, string>;
|
|
1101
|
+
payload?: Record<string, unknown>;
|
|
1102
|
+
fcm_options?: ApnsFcmOptions;
|
|
1103
|
+
}
|
|
1104
|
+
interface ApnsFcmOptions {
|
|
1105
|
+
analytics_label?: string;
|
|
1106
|
+
image?: string;
|
|
1107
|
+
}
|
|
1108
|
+
interface FcmOptions {
|
|
1109
|
+
analytics_label?: string;
|
|
1110
|
+
}
|
|
1111
|
+
interface SendResponse {
|
|
1112
|
+
/** Full resource name: "projects/{id}/messages/{id}" */
|
|
1113
|
+
name: string;
|
|
1114
|
+
}
|
|
1115
|
+
interface TopicManagementResponse {
|
|
1116
|
+
successCount: number;
|
|
1117
|
+
failureCount: number;
|
|
1118
|
+
errors: TopicManagementError[];
|
|
1119
|
+
}
|
|
1120
|
+
interface TopicManagementError {
|
|
1121
|
+
index: number;
|
|
1122
|
+
error: string;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Firebase Cloud Messaging (FCM) Client
|
|
1127
|
+
* Implements FCM HTTP v1 API for sending messages and managing topic subscriptions.
|
|
1128
|
+
*/
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Send a message via FCM HTTP v1 API.
|
|
1132
|
+
*
|
|
1133
|
+
* Exactly one of `message.token`, `message.topic`, or `message.condition` must be set.
|
|
1134
|
+
*
|
|
1135
|
+
* @param message - The message to send
|
|
1136
|
+
* @returns The message resource name (e.g. "projects/my-project/messages/123")
|
|
1137
|
+
*/
|
|
1138
|
+
declare function sendMessage(message: Message): Promise<string>;
|
|
1139
|
+
/**
|
|
1140
|
+
* Subscribe device tokens to a topic.
|
|
1141
|
+
*
|
|
1142
|
+
* @param tokens - Array of device registration tokens (max 1000)
|
|
1143
|
+
* @param topic - Topic name (with or without "/topics/" prefix)
|
|
1144
|
+
* @returns Results with success/failure counts and per-token errors
|
|
1145
|
+
*/
|
|
1146
|
+
declare function subscribeToTopic(tokens: string[], topic: string): Promise<TopicManagementResponse>;
|
|
1147
|
+
/**
|
|
1148
|
+
* Unsubscribe device tokens from a topic.
|
|
1149
|
+
*
|
|
1150
|
+
* @param tokens - Array of device registration tokens (max 1000)
|
|
1151
|
+
* @param topic - Topic name (with or without "/topics/" prefix)
|
|
1152
|
+
* @returns Results with success/failure counts and per-token errors
|
|
1153
|
+
*/
|
|
1154
|
+
declare function unsubscribeFromTopic(tokens: string[], topic: string): Promise<TopicManagementResponse>;
|
|
1155
|
+
|
|
1009
1156
|
/**
|
|
1010
1157
|
* Firebase Admin SDK v8 - Field Value Helpers
|
|
1011
1158
|
* Special field values for Firestore operations
|
|
@@ -1103,4 +1250,4 @@ declare function getAdminAccessToken(): Promise<string>;
|
|
|
1103
1250
|
*/
|
|
1104
1251
|
declare function clearTokenCache(): void;
|
|
1105
1252
|
|
|
1106
|
-
export { type BatchWrite, type BatchWriteResult, type CreateUserRequest, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type ListUsersResult, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UpdateUserRequest, type UploadOptions, type UserInfo, type UserRecord, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, createUser, deleteDocument, deleteFile, deleteUser, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserByEmail, getUserByUid, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, listUsers, queryDocuments, setCustomUserClaims, setDocument, signInWithCustomToken, updateDocument, updateUser, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
|
1253
|
+
export { type AndroidConfig, type AndroidNotification, type ApnsConfig, type BatchWrite, type BatchWriteResult, type CreateUserRequest, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, type Notification as FcmNotification, type FcmOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type ListUsersResult, type Message, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type SendResponse, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type TopicManagementError, type TopicManagementResponse, type UpdateOptions, type UpdateUserRequest, type UploadOptions, type UserInfo, type UserRecord, type WebpushConfig, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, createUser, deleteDocument, deleteFile, deleteUser, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserByEmail, getUserByUid, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, listUsers, queryDocuments, sendMessage, setCustomUserClaims, setDocument, signInWithCustomToken, subscribeToTopic, unsubscribeFromTopic, updateDocument, updateUser, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
package/dist/index.d.ts
CHANGED
|
@@ -1006,6 +1006,153 @@ interface ResumableUploadOptions extends UploadOptions {
|
|
|
1006
1006
|
*/
|
|
1007
1007
|
declare function uploadFileResumable(path: string, data: ArrayBuffer | Uint8Array | Blob | ReadableStream<Uint8Array>, contentType: string, options?: ResumableUploadOptions): Promise<FileMetadata>;
|
|
1008
1008
|
|
|
1009
|
+
/**
|
|
1010
|
+
* Firebase Cloud Messaging (FCM) Types
|
|
1011
|
+
* Based on FCM HTTP v1 API specification
|
|
1012
|
+
*/
|
|
1013
|
+
interface Message {
|
|
1014
|
+
/** Device registration token (mutually exclusive with topic/condition) */
|
|
1015
|
+
token?: string;
|
|
1016
|
+
/** Topic name (mutually exclusive with token/condition) */
|
|
1017
|
+
topic?: string;
|
|
1018
|
+
/** Condition expression for topic combinations (mutually exclusive with token/topic) */
|
|
1019
|
+
condition?: string;
|
|
1020
|
+
/** Basic notification payload displayed on all platforms */
|
|
1021
|
+
notification?: Notification;
|
|
1022
|
+
/** Custom key-value data payload */
|
|
1023
|
+
data?: Record<string, string>;
|
|
1024
|
+
/** Android-specific configuration */
|
|
1025
|
+
android?: AndroidConfig;
|
|
1026
|
+
/** Web push protocol configuration */
|
|
1027
|
+
webpush?: WebpushConfig;
|
|
1028
|
+
/** Apple Push Notification Service configuration */
|
|
1029
|
+
apns?: ApnsConfig;
|
|
1030
|
+
/** FCM-specific options */
|
|
1031
|
+
fcm_options?: FcmOptions;
|
|
1032
|
+
}
|
|
1033
|
+
interface Notification {
|
|
1034
|
+
title?: string;
|
|
1035
|
+
body?: string;
|
|
1036
|
+
image?: string;
|
|
1037
|
+
}
|
|
1038
|
+
interface AndroidConfig {
|
|
1039
|
+
collapse_key?: string;
|
|
1040
|
+
priority?: 'high' | 'normal';
|
|
1041
|
+
ttl?: string;
|
|
1042
|
+
restricted_package_name?: string;
|
|
1043
|
+
data?: Record<string, string>;
|
|
1044
|
+
notification?: AndroidNotification;
|
|
1045
|
+
fcm_options?: AndroidFcmOptions;
|
|
1046
|
+
direct_boot_ok?: boolean;
|
|
1047
|
+
}
|
|
1048
|
+
interface AndroidNotification {
|
|
1049
|
+
title?: string;
|
|
1050
|
+
body?: string;
|
|
1051
|
+
icon?: string;
|
|
1052
|
+
color?: string;
|
|
1053
|
+
sound?: string;
|
|
1054
|
+
tag?: string;
|
|
1055
|
+
click_action?: string;
|
|
1056
|
+
body_loc_key?: string;
|
|
1057
|
+
body_loc_args?: string[];
|
|
1058
|
+
title_loc_key?: string;
|
|
1059
|
+
title_loc_args?: string[];
|
|
1060
|
+
channel_id?: string;
|
|
1061
|
+
ticker?: string;
|
|
1062
|
+
sticky?: boolean;
|
|
1063
|
+
event_time?: string;
|
|
1064
|
+
local_only?: boolean;
|
|
1065
|
+
notification_priority?: AndroidNotificationPriority;
|
|
1066
|
+
default_sound?: boolean;
|
|
1067
|
+
default_vibrate_timings?: boolean;
|
|
1068
|
+
default_light_settings?: boolean;
|
|
1069
|
+
vibrate_timings?: string[];
|
|
1070
|
+
visibility?: 'VISIBILITY_UNSPECIFIED' | 'PRIVATE' | 'PUBLIC' | 'SECRET';
|
|
1071
|
+
notification_count?: number;
|
|
1072
|
+
light_settings?: LightSettings;
|
|
1073
|
+
image?: string;
|
|
1074
|
+
}
|
|
1075
|
+
type AndroidNotificationPriority = 'PRIORITY_UNSPECIFIED' | 'PRIORITY_MIN' | 'PRIORITY_LOW' | 'PRIORITY_DEFAULT' | 'PRIORITY_HIGH' | 'PRIORITY_MAX';
|
|
1076
|
+
interface LightSettings {
|
|
1077
|
+
color: {
|
|
1078
|
+
red: number;
|
|
1079
|
+
green: number;
|
|
1080
|
+
blue: number;
|
|
1081
|
+
alpha: number;
|
|
1082
|
+
};
|
|
1083
|
+
light_on_duration: string;
|
|
1084
|
+
light_off_duration: string;
|
|
1085
|
+
}
|
|
1086
|
+
interface AndroidFcmOptions {
|
|
1087
|
+
analytics_label?: string;
|
|
1088
|
+
}
|
|
1089
|
+
interface WebpushConfig {
|
|
1090
|
+
headers?: Record<string, string>;
|
|
1091
|
+
data?: Record<string, string>;
|
|
1092
|
+
notification?: Record<string, unknown>;
|
|
1093
|
+
fcm_options?: WebpushFcmOptions;
|
|
1094
|
+
}
|
|
1095
|
+
interface WebpushFcmOptions {
|
|
1096
|
+
link?: string;
|
|
1097
|
+
analytics_label?: string;
|
|
1098
|
+
}
|
|
1099
|
+
interface ApnsConfig {
|
|
1100
|
+
headers?: Record<string, string>;
|
|
1101
|
+
payload?: Record<string, unknown>;
|
|
1102
|
+
fcm_options?: ApnsFcmOptions;
|
|
1103
|
+
}
|
|
1104
|
+
interface ApnsFcmOptions {
|
|
1105
|
+
analytics_label?: string;
|
|
1106
|
+
image?: string;
|
|
1107
|
+
}
|
|
1108
|
+
interface FcmOptions {
|
|
1109
|
+
analytics_label?: string;
|
|
1110
|
+
}
|
|
1111
|
+
interface SendResponse {
|
|
1112
|
+
/** Full resource name: "projects/{id}/messages/{id}" */
|
|
1113
|
+
name: string;
|
|
1114
|
+
}
|
|
1115
|
+
interface TopicManagementResponse {
|
|
1116
|
+
successCount: number;
|
|
1117
|
+
failureCount: number;
|
|
1118
|
+
errors: TopicManagementError[];
|
|
1119
|
+
}
|
|
1120
|
+
interface TopicManagementError {
|
|
1121
|
+
index: number;
|
|
1122
|
+
error: string;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Firebase Cloud Messaging (FCM) Client
|
|
1127
|
+
* Implements FCM HTTP v1 API for sending messages and managing topic subscriptions.
|
|
1128
|
+
*/
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Send a message via FCM HTTP v1 API.
|
|
1132
|
+
*
|
|
1133
|
+
* Exactly one of `message.token`, `message.topic`, or `message.condition` must be set.
|
|
1134
|
+
*
|
|
1135
|
+
* @param message - The message to send
|
|
1136
|
+
* @returns The message resource name (e.g. "projects/my-project/messages/123")
|
|
1137
|
+
*/
|
|
1138
|
+
declare function sendMessage(message: Message): Promise<string>;
|
|
1139
|
+
/**
|
|
1140
|
+
* Subscribe device tokens to a topic.
|
|
1141
|
+
*
|
|
1142
|
+
* @param tokens - Array of device registration tokens (max 1000)
|
|
1143
|
+
* @param topic - Topic name (with or without "/topics/" prefix)
|
|
1144
|
+
* @returns Results with success/failure counts and per-token errors
|
|
1145
|
+
*/
|
|
1146
|
+
declare function subscribeToTopic(tokens: string[], topic: string): Promise<TopicManagementResponse>;
|
|
1147
|
+
/**
|
|
1148
|
+
* Unsubscribe device tokens from a topic.
|
|
1149
|
+
*
|
|
1150
|
+
* @param tokens - Array of device registration tokens (max 1000)
|
|
1151
|
+
* @param topic - Topic name (with or without "/topics/" prefix)
|
|
1152
|
+
* @returns Results with success/failure counts and per-token errors
|
|
1153
|
+
*/
|
|
1154
|
+
declare function unsubscribeFromTopic(tokens: string[], topic: string): Promise<TopicManagementResponse>;
|
|
1155
|
+
|
|
1009
1156
|
/**
|
|
1010
1157
|
* Firebase Admin SDK v8 - Field Value Helpers
|
|
1011
1158
|
* Special field values for Firestore operations
|
|
@@ -1103,4 +1250,4 @@ declare function getAdminAccessToken(): Promise<string>;
|
|
|
1103
1250
|
*/
|
|
1104
1251
|
declare function clearTokenCache(): void;
|
|
1105
1252
|
|
|
1106
|
-
export { type BatchWrite, type BatchWriteResult, type CreateUserRequest, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type ListUsersResult, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UpdateUserRequest, type UploadOptions, type UserInfo, type UserRecord, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, createUser, deleteDocument, deleteFile, deleteUser, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserByEmail, getUserByUid, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, listUsers, queryDocuments, setCustomUserClaims, setDocument, signInWithCustomToken, updateDocument, updateUser, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
|
1253
|
+
export { type AndroidConfig, type AndroidNotification, type ApnsConfig, type BatchWrite, type BatchWriteResult, type CreateUserRequest, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, type Notification as FcmNotification, type FcmOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type ListUsersResult, type Message, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type SendResponse, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type TopicManagementError, type TopicManagementResponse, type UpdateOptions, type UpdateUserRequest, type UploadOptions, type UserInfo, type UserRecord, type WebpushConfig, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, createUser, deleteDocument, deleteFile, deleteUser, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserByEmail, getUserByUid, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, listUsers, queryDocuments, sendMessage, setCustomUserClaims, setDocument, signInWithCustomToken, subscribeToTopic, unsubscribeFromTopic, updateDocument, updateUser, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
package/dist/index.js
CHANGED
|
@@ -231,9 +231,12 @@ __export(index_exports, {
|
|
|
231
231
|
listFiles: () => listFiles,
|
|
232
232
|
listUsers: () => listUsers,
|
|
233
233
|
queryDocuments: () => queryDocuments,
|
|
234
|
+
sendMessage: () => sendMessage,
|
|
234
235
|
setCustomUserClaims: () => setCustomUserClaims,
|
|
235
236
|
setDocument: () => setDocument,
|
|
236
237
|
signInWithCustomToken: () => signInWithCustomToken,
|
|
238
|
+
subscribeToTopic: () => subscribeToTopic,
|
|
239
|
+
unsubscribeFromTopic: () => unsubscribeFromTopic,
|
|
237
240
|
updateDocument: () => updateDocument,
|
|
238
241
|
updateUser: () => updateUser,
|
|
239
242
|
uploadFile: () => uploadFile,
|
|
@@ -2142,6 +2145,96 @@ async function uploadFromStream(bucket, path, stream, contentType, chunkSize, op
|
|
|
2142
2145
|
}
|
|
2143
2146
|
}
|
|
2144
2147
|
|
|
2148
|
+
// src/messaging/client.ts
|
|
2149
|
+
init_token_generation();
|
|
2150
|
+
init_config();
|
|
2151
|
+
var FCM_BASE_URL = "https://fcm.googleapis.com/v1";
|
|
2152
|
+
var IID_BASE_URL = "https://iid.googleapis.com/iid/v1";
|
|
2153
|
+
async function sendMessage(message) {
|
|
2154
|
+
const targets = [message.token, message.topic, message.condition].filter(Boolean);
|
|
2155
|
+
if (targets.length === 0) {
|
|
2156
|
+
throw new Error("One of token, topic, or condition must be specified");
|
|
2157
|
+
}
|
|
2158
|
+
if (targets.length > 1) {
|
|
2159
|
+
throw new Error("Only one of token, topic, or condition can be specified");
|
|
2160
|
+
}
|
|
2161
|
+
const config = getConfig();
|
|
2162
|
+
const accessToken = await getAdminAccessToken();
|
|
2163
|
+
const url = `${FCM_BASE_URL}/projects/${config.projectId}/messages:send`;
|
|
2164
|
+
const response = await fetch(url, {
|
|
2165
|
+
method: "POST",
|
|
2166
|
+
headers: {
|
|
2167
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
2168
|
+
"Content-Type": "application/json"
|
|
2169
|
+
},
|
|
2170
|
+
body: JSON.stringify({ message })
|
|
2171
|
+
});
|
|
2172
|
+
if (!response.ok) {
|
|
2173
|
+
let errorDetail;
|
|
2174
|
+
try {
|
|
2175
|
+
const errorBody = await response.json();
|
|
2176
|
+
errorDetail = JSON.stringify(errorBody);
|
|
2177
|
+
} catch {
|
|
2178
|
+
errorDetail = await response.text();
|
|
2179
|
+
}
|
|
2180
|
+
throw new Error(`FCM send failed (${response.status}): ${errorDetail}`);
|
|
2181
|
+
}
|
|
2182
|
+
const result = await response.json();
|
|
2183
|
+
return result.name;
|
|
2184
|
+
}
|
|
2185
|
+
async function subscribeToTopic(tokens, topic) {
|
|
2186
|
+
return manageTopicSubscription(tokens, topic, "batchAdd");
|
|
2187
|
+
}
|
|
2188
|
+
async function unsubscribeFromTopic(tokens, topic) {
|
|
2189
|
+
return manageTopicSubscription(tokens, topic, "batchRemove");
|
|
2190
|
+
}
|
|
2191
|
+
async function manageTopicSubscription(tokens, topic, action) {
|
|
2192
|
+
if (tokens.length === 0) {
|
|
2193
|
+
throw new Error("At least one token is required");
|
|
2194
|
+
}
|
|
2195
|
+
if (tokens.length > 1e3) {
|
|
2196
|
+
throw new Error("Maximum 1000 tokens per request");
|
|
2197
|
+
}
|
|
2198
|
+
const accessToken = await getAdminAccessToken();
|
|
2199
|
+
const url = `${IID_BASE_URL}:${action}`;
|
|
2200
|
+
const topicPath = topic.startsWith("/topics/") ? topic : `/topics/${topic}`;
|
|
2201
|
+
const response = await fetch(url, {
|
|
2202
|
+
method: "POST",
|
|
2203
|
+
headers: {
|
|
2204
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
2205
|
+
"Content-Type": "application/json",
|
|
2206
|
+
"access_token_auth": "true"
|
|
2207
|
+
},
|
|
2208
|
+
body: JSON.stringify({
|
|
2209
|
+
to: topicPath,
|
|
2210
|
+
registration_tokens: tokens
|
|
2211
|
+
})
|
|
2212
|
+
});
|
|
2213
|
+
if (!response.ok) {
|
|
2214
|
+
let errorDetail;
|
|
2215
|
+
try {
|
|
2216
|
+
errorDetail = await response.text();
|
|
2217
|
+
} catch {
|
|
2218
|
+
errorDetail = `HTTP ${response.status}`;
|
|
2219
|
+
}
|
|
2220
|
+
throw new Error(`FCM topic ${action} failed (${response.status}): ${errorDetail}`);
|
|
2221
|
+
}
|
|
2222
|
+
const result = await response.json();
|
|
2223
|
+
let successCount = 0;
|
|
2224
|
+
let failureCount = 0;
|
|
2225
|
+
const errors = [];
|
|
2226
|
+
for (let i = 0; i < result.results.length; i++) {
|
|
2227
|
+
const entry = result.results[i];
|
|
2228
|
+
if (entry.error) {
|
|
2229
|
+
failureCount++;
|
|
2230
|
+
errors.push({ index: i, error: entry.error });
|
|
2231
|
+
} else {
|
|
2232
|
+
successCount++;
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
return { successCount, failureCount, errors };
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2145
2238
|
// src/index.ts
|
|
2146
2239
|
init_token_generation();
|
|
2147
2240
|
init_service_account();
|
|
@@ -2178,9 +2271,12 @@ init_service_account();
|
|
|
2178
2271
|
listFiles,
|
|
2179
2272
|
listUsers,
|
|
2180
2273
|
queryDocuments,
|
|
2274
|
+
sendMessage,
|
|
2181
2275
|
setCustomUserClaims,
|
|
2182
2276
|
setDocument,
|
|
2183
2277
|
signInWithCustomToken,
|
|
2278
|
+
subscribeToTopic,
|
|
2279
|
+
unsubscribeFromTopic,
|
|
2184
2280
|
updateDocument,
|
|
2185
2281
|
updateUser,
|
|
2186
2282
|
uploadFile,
|
package/dist/index.mjs
CHANGED
|
@@ -1891,6 +1891,94 @@ async function uploadFromStream(bucket, path, stream, contentType, chunkSize, op
|
|
|
1891
1891
|
reader.releaseLock();
|
|
1892
1892
|
}
|
|
1893
1893
|
}
|
|
1894
|
+
|
|
1895
|
+
// src/messaging/client.ts
|
|
1896
|
+
var FCM_BASE_URL = "https://fcm.googleapis.com/v1";
|
|
1897
|
+
var IID_BASE_URL = "https://iid.googleapis.com/iid/v1";
|
|
1898
|
+
async function sendMessage(message) {
|
|
1899
|
+
const targets = [message.token, message.topic, message.condition].filter(Boolean);
|
|
1900
|
+
if (targets.length === 0) {
|
|
1901
|
+
throw new Error("One of token, topic, or condition must be specified");
|
|
1902
|
+
}
|
|
1903
|
+
if (targets.length > 1) {
|
|
1904
|
+
throw new Error("Only one of token, topic, or condition can be specified");
|
|
1905
|
+
}
|
|
1906
|
+
const config = getConfig();
|
|
1907
|
+
const accessToken = await getAdminAccessToken();
|
|
1908
|
+
const url = `${FCM_BASE_URL}/projects/${config.projectId}/messages:send`;
|
|
1909
|
+
const response = await fetch(url, {
|
|
1910
|
+
method: "POST",
|
|
1911
|
+
headers: {
|
|
1912
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
1913
|
+
"Content-Type": "application/json"
|
|
1914
|
+
},
|
|
1915
|
+
body: JSON.stringify({ message })
|
|
1916
|
+
});
|
|
1917
|
+
if (!response.ok) {
|
|
1918
|
+
let errorDetail;
|
|
1919
|
+
try {
|
|
1920
|
+
const errorBody = await response.json();
|
|
1921
|
+
errorDetail = JSON.stringify(errorBody);
|
|
1922
|
+
} catch {
|
|
1923
|
+
errorDetail = await response.text();
|
|
1924
|
+
}
|
|
1925
|
+
throw new Error(`FCM send failed (${response.status}): ${errorDetail}`);
|
|
1926
|
+
}
|
|
1927
|
+
const result = await response.json();
|
|
1928
|
+
return result.name;
|
|
1929
|
+
}
|
|
1930
|
+
async function subscribeToTopic(tokens, topic) {
|
|
1931
|
+
return manageTopicSubscription(tokens, topic, "batchAdd");
|
|
1932
|
+
}
|
|
1933
|
+
async function unsubscribeFromTopic(tokens, topic) {
|
|
1934
|
+
return manageTopicSubscription(tokens, topic, "batchRemove");
|
|
1935
|
+
}
|
|
1936
|
+
async function manageTopicSubscription(tokens, topic, action) {
|
|
1937
|
+
if (tokens.length === 0) {
|
|
1938
|
+
throw new Error("At least one token is required");
|
|
1939
|
+
}
|
|
1940
|
+
if (tokens.length > 1e3) {
|
|
1941
|
+
throw new Error("Maximum 1000 tokens per request");
|
|
1942
|
+
}
|
|
1943
|
+
const accessToken = await getAdminAccessToken();
|
|
1944
|
+
const url = `${IID_BASE_URL}:${action}`;
|
|
1945
|
+
const topicPath = topic.startsWith("/topics/") ? topic : `/topics/${topic}`;
|
|
1946
|
+
const response = await fetch(url, {
|
|
1947
|
+
method: "POST",
|
|
1948
|
+
headers: {
|
|
1949
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
1950
|
+
"Content-Type": "application/json",
|
|
1951
|
+
"access_token_auth": "true"
|
|
1952
|
+
},
|
|
1953
|
+
body: JSON.stringify({
|
|
1954
|
+
to: topicPath,
|
|
1955
|
+
registration_tokens: tokens
|
|
1956
|
+
})
|
|
1957
|
+
});
|
|
1958
|
+
if (!response.ok) {
|
|
1959
|
+
let errorDetail;
|
|
1960
|
+
try {
|
|
1961
|
+
errorDetail = await response.text();
|
|
1962
|
+
} catch {
|
|
1963
|
+
errorDetail = `HTTP ${response.status}`;
|
|
1964
|
+
}
|
|
1965
|
+
throw new Error(`FCM topic ${action} failed (${response.status}): ${errorDetail}`);
|
|
1966
|
+
}
|
|
1967
|
+
const result = await response.json();
|
|
1968
|
+
let successCount = 0;
|
|
1969
|
+
let failureCount = 0;
|
|
1970
|
+
const errors = [];
|
|
1971
|
+
for (let i = 0; i < result.results.length; i++) {
|
|
1972
|
+
const entry = result.results[i];
|
|
1973
|
+
if (entry.error) {
|
|
1974
|
+
failureCount++;
|
|
1975
|
+
errors.push({ index: i, error: entry.error });
|
|
1976
|
+
} else {
|
|
1977
|
+
successCount++;
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
return { successCount, failureCount, errors };
|
|
1981
|
+
}
|
|
1894
1982
|
export {
|
|
1895
1983
|
FieldValue,
|
|
1896
1984
|
addDocument,
|
|
@@ -1923,9 +2011,12 @@ export {
|
|
|
1923
2011
|
listFiles,
|
|
1924
2012
|
listUsers,
|
|
1925
2013
|
queryDocuments,
|
|
2014
|
+
sendMessage,
|
|
1926
2015
|
setCustomUserClaims,
|
|
1927
2016
|
setDocument,
|
|
1928
2017
|
signInWithCustomToken,
|
|
2018
|
+
subscribeToTopic,
|
|
2019
|
+
unsubscribeFromTopic,
|
|
1929
2020
|
updateDocument,
|
|
1930
2021
|
updateUser,
|
|
1931
2022
|
uploadFile,
|
package/package.json
CHANGED