@prmichaelsen/firebase-admin-sdk-v8 2.6.0 → 2.7.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.
@@ -13,7 +13,9 @@
13
13
  "WebFetch(domain:agentbase.me)",
14
14
  "WebSearch",
15
15
  "WebFetch(domain:firebase.google.com)",
16
- "WebFetch(domain:developers.google.com)"
16
+ "WebFetch(domain:developers.google.com)",
17
+ "Bash(npx tsc:*)",
18
+ "Bash(node --env-file=.env node_modules/.bin/jest --config jest.e2e.config.js --testPathPatterns='firestore/operations.e2e' 2>&1 | tail -20)"
17
19
  ]
18
20
  }
19
21
  }
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ 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.7.0] - 2026-03-12
9
+
10
+ ### Added
11
+ - **Firestore Batch Get (`getAll`)**: Fetch multiple documents in a single REST API call
12
+ - `getAll(collectionPath, documentIds)` - Batch get up to 100 documents via `documents:batchGet` endpoint
13
+ - Returns results in the same order as input document IDs
14
+ - Missing documents return `null` (no throw)
15
+ - Enforces 100-document limit with clear error message
16
+ - Supports subcollection paths
17
+ - 8 unit tests + 5 e2e tests
18
+
19
+ ### Changed
20
+ - Total unit tests increased from 498 to 506 (+8 tests)
21
+
8
22
  ## [2.6.0] - 2026-03-07
9
23
 
10
24
  ### Added
package/dist/index.d.mts CHANGED
@@ -640,6 +640,22 @@ declare function queryDocuments(collectionPath: string, options?: QueryOptions):
640
640
  id: string;
641
641
  data: DataObject;
642
642
  }>>;
643
+ /**
644
+ * Batch get multiple documents from Firestore
645
+ * Uses the documents:batchGet REST API endpoint
646
+ *
647
+ * @param collectionPath - The collection containing the documents
648
+ * @param documentIds - Array of document IDs to fetch (max 100)
649
+ * @returns Array of results in the same order as documentIds. Missing documents return null.
650
+ * @throws {Error} If the operation fails or more than 100 documents requested
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * const users = await getAll('users', ['user1', 'user2', 'user3']);
655
+ * // users[0] = { name: 'Alice', ... } or null if not found
656
+ * ```
657
+ */
658
+ declare function getAll(collectionPath: string, documentIds: string[]): Promise<(DataObject | null)[]>;
643
659
  /**
644
660
  * Perform batch write operations (set, update, delete)
645
661
  *
@@ -1250,4 +1266,4 @@ declare function getAdminAccessToken(): Promise<string>;
1250
1266
  */
1251
1267
  declare function clearTokenCache(): void;
1252
1268
 
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 };
1269
+ 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, getAll, 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
@@ -640,6 +640,22 @@ declare function queryDocuments(collectionPath: string, options?: QueryOptions):
640
640
  id: string;
641
641
  data: DataObject;
642
642
  }>>;
643
+ /**
644
+ * Batch get multiple documents from Firestore
645
+ * Uses the documents:batchGet REST API endpoint
646
+ *
647
+ * @param collectionPath - The collection containing the documents
648
+ * @param documentIds - Array of document IDs to fetch (max 100)
649
+ * @returns Array of results in the same order as documentIds. Missing documents return null.
650
+ * @throws {Error} If the operation fails or more than 100 documents requested
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * const users = await getAll('users', ['user1', 'user2', 'user3']);
655
+ * // users[0] = { name: 'Alice', ... } or null if not found
656
+ * ```
657
+ */
658
+ declare function getAll(collectionPath: string, documentIds: string[]): Promise<(DataObject | null)[]>;
643
659
  /**
644
660
  * Perform batch write operations (set, update, delete)
645
661
  *
@@ -1250,4 +1266,4 @@ declare function getAdminAccessToken(): Promise<string>;
1250
1266
  */
1251
1267
  declare function clearTokenCache(): void;
1252
1268
 
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 };
1269
+ 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, getAll, 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
@@ -216,6 +216,7 @@ __export(index_exports, {
216
216
  fileExists: () => fileExists,
217
217
  generateSignedUrl: () => generateSignedUrl,
218
218
  getAdminAccessToken: () => getAdminAccessToken,
219
+ getAll: () => getAll,
219
220
  getAuth: () => getAuth,
220
221
  getConfig: () => getConfig,
221
222
  getDocument: () => getDocument,
@@ -1514,6 +1515,44 @@ async function queryDocuments(collectionPath, options) {
1514
1515
  data: convertFromFirestoreFormat(result.document.fields)
1515
1516
  }));
1516
1517
  }
1518
+ async function getAll(collectionPath, documentIds) {
1519
+ if (documentIds.length === 0) return [];
1520
+ if (documentIds.length > 100) {
1521
+ throw new Error("getAll supports a maximum of 100 documents per request");
1522
+ }
1523
+ for (const id of documentIds) {
1524
+ validateDocumentPath("collectionPath", collectionPath, id);
1525
+ }
1526
+ const accessToken = await getAdminAccessToken();
1527
+ const projectId = getProjectId();
1528
+ const basePath = `projects/${projectId}/databases/(default)/documents`;
1529
+ const documents = documentIds.map((id) => `${basePath}/${collectionPath}/${id}`);
1530
+ const url = `${FIRESTORE_API}/${basePath}:batchGet`;
1531
+ const response = await fetch(url, {
1532
+ method: "POST",
1533
+ headers: {
1534
+ "Authorization": `Bearer ${accessToken}`,
1535
+ "Content-Type": "application/json"
1536
+ },
1537
+ body: JSON.stringify({ documents })
1538
+ });
1539
+ if (!response.ok) {
1540
+ const errorText = await response.text();
1541
+ throw new Error(`Failed to batch get documents: ${errorText}`);
1542
+ }
1543
+ const results = await response.json();
1544
+ const resultMap = /* @__PURE__ */ new Map();
1545
+ for (const result of results) {
1546
+ if (result.found) {
1547
+ const name = result.found.name;
1548
+ const data = convertFromFirestoreFormat(result.found.fields);
1549
+ resultMap.set(name, data);
1550
+ } else if (result.missing) {
1551
+ resultMap.set(result.missing, null);
1552
+ }
1553
+ }
1554
+ return documents.map((docPath) => resultMap.get(docPath) ?? null);
1555
+ }
1517
1556
  async function batchWrite(operations) {
1518
1557
  const accessToken = await getAdminAccessToken();
1519
1558
  const projectId = getProjectId();
@@ -2158,9 +2197,9 @@ async function sendMessage(message) {
2158
2197
  if (targets.length > 1) {
2159
2198
  throw new Error("Only one of token, topic, or condition can be specified");
2160
2199
  }
2161
- const config = getConfig();
2162
2200
  const accessToken = await getAdminAccessToken();
2163
- const url = `${FCM_BASE_URL}/projects/${config.projectId}/messages:send`;
2201
+ const projectId = getProjectId();
2202
+ const url = `${FCM_BASE_URL}/projects/${projectId}/messages:send`;
2164
2203
  const response = await fetch(url, {
2165
2204
  method: "POST",
2166
2205
  headers: {
@@ -2256,6 +2295,7 @@ init_service_account();
2256
2295
  fileExists,
2257
2296
  generateSignedUrl,
2258
2297
  getAdminAccessToken,
2298
+ getAll,
2259
2299
  getAuth,
2260
2300
  getConfig,
2261
2301
  getDocument,
package/dist/index.mjs CHANGED
@@ -1266,6 +1266,44 @@ async function queryDocuments(collectionPath, options) {
1266
1266
  data: convertFromFirestoreFormat(result.document.fields)
1267
1267
  }));
1268
1268
  }
1269
+ async function getAll(collectionPath, documentIds) {
1270
+ if (documentIds.length === 0) return [];
1271
+ if (documentIds.length > 100) {
1272
+ throw new Error("getAll supports a maximum of 100 documents per request");
1273
+ }
1274
+ for (const id of documentIds) {
1275
+ validateDocumentPath("collectionPath", collectionPath, id);
1276
+ }
1277
+ const accessToken = await getAdminAccessToken();
1278
+ const projectId = getProjectId();
1279
+ const basePath = `projects/${projectId}/databases/(default)/documents`;
1280
+ const documents = documentIds.map((id) => `${basePath}/${collectionPath}/${id}`);
1281
+ const url = `${FIRESTORE_API}/${basePath}:batchGet`;
1282
+ const response = await fetch(url, {
1283
+ method: "POST",
1284
+ headers: {
1285
+ "Authorization": `Bearer ${accessToken}`,
1286
+ "Content-Type": "application/json"
1287
+ },
1288
+ body: JSON.stringify({ documents })
1289
+ });
1290
+ if (!response.ok) {
1291
+ const errorText = await response.text();
1292
+ throw new Error(`Failed to batch get documents: ${errorText}`);
1293
+ }
1294
+ const results = await response.json();
1295
+ const resultMap = /* @__PURE__ */ new Map();
1296
+ for (const result of results) {
1297
+ if (result.found) {
1298
+ const name = result.found.name;
1299
+ const data = convertFromFirestoreFormat(result.found.fields);
1300
+ resultMap.set(name, data);
1301
+ } else if (result.missing) {
1302
+ resultMap.set(result.missing, null);
1303
+ }
1304
+ }
1305
+ return documents.map((docPath) => resultMap.get(docPath) ?? null);
1306
+ }
1269
1307
  async function batchWrite(operations) {
1270
1308
  const accessToken = await getAdminAccessToken();
1271
1309
  const projectId = getProjectId();
@@ -1903,9 +1941,9 @@ async function sendMessage(message) {
1903
1941
  if (targets.length > 1) {
1904
1942
  throw new Error("Only one of token, topic, or condition can be specified");
1905
1943
  }
1906
- const config = getConfig();
1907
1944
  const accessToken = await getAdminAccessToken();
1908
- const url = `${FCM_BASE_URL}/projects/${config.projectId}/messages:send`;
1945
+ const projectId = getProjectId();
1946
+ const url = `${FCM_BASE_URL}/projects/${projectId}/messages:send`;
1909
1947
  const response = await fetch(url, {
1910
1948
  method: "POST",
1911
1949
  headers: {
@@ -1996,6 +2034,7 @@ export {
1996
2034
  fileExists,
1997
2035
  generateSignedUrl,
1998
2036
  getAdminAccessToken,
2037
+ getAll,
1999
2038
  getAuth,
2000
2039
  getConfig,
2001
2040
  getDocument,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/firebase-admin-sdk-v8",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Firebase Admin SDK for Cloudflare Workers and edge runtimes using REST APIs",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",