firebase-tools 14.10.1 → 14.11.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.
Files changed (36) hide show
  1. package/lib/api.js +3 -1
  2. package/lib/apptesting/invokeTests.js +40 -0
  3. package/lib/apptesting/parseTestFiles.js +75 -0
  4. package/lib/apptesting/types.js +18 -0
  5. package/lib/commands/apptesting-execute.js +102 -0
  6. package/lib/commands/index.js +4 -0
  7. package/lib/commands/init.js +7 -0
  8. package/lib/deploy/functions/runtimes/discovery/index.js +53 -4
  9. package/lib/deploy/functions/runtimes/node/index.js +74 -44
  10. package/lib/emulator/downloadableEmulatorInfo.json +18 -18
  11. package/lib/emulator/env.js +2 -1
  12. package/lib/emulator/hub.js +1 -2
  13. package/lib/emulator/tasksEmulator.js +1 -1
  14. package/lib/emulator/ui.js +3 -1
  15. package/lib/experiments.js +4 -0
  16. package/lib/firestore/api.js +1 -11
  17. package/lib/init/features/aitools/claude.js +44 -0
  18. package/lib/init/features/aitools/cursor.js +62 -0
  19. package/lib/init/features/aitools/gemini.js +58 -0
  20. package/lib/init/features/aitools/index.js +28 -0
  21. package/lib/init/features/aitools/promptUpdater.js +109 -0
  22. package/lib/init/features/aitools/studio.js +17 -0
  23. package/lib/init/features/aitools/types.js +2 -0
  24. package/lib/init/features/aitools.js +83 -0
  25. package/lib/init/features/apptesting/index.js +29 -0
  26. package/lib/init/features/index.js +4 -1
  27. package/lib/init/index.js +5 -0
  28. package/lib/mcp/index.js +32 -1
  29. package/lib/utils.js +21 -1
  30. package/package.json +2 -1
  31. package/prompts/FIREBASE.md +122 -0
  32. package/prompts/FIREBASE_FUNCTIONS.md +221 -0
  33. package/schema/apptesting-yaml.json +64 -0
  34. package/templates/init/aitools/cursor-rules-header.txt +8 -0
  35. package/templates/init/aitools/gemini-extension.json +11 -0
  36. package/templates/init/apptesting/smoke_test.yaml +6 -0
@@ -0,0 +1,122 @@
1
+ # Firebase CLI Context
2
+
3
+ <project-structure>
4
+ ```
5
+ project/
6
+ ├── firebase.json # Main configuration
7
+ ├── .firebaserc # Project aliases
8
+ ├── firestore.rules # Security rules
9
+ ├── functions/ # Cloud Functions
10
+ ├── public/ # Hosting files
11
+ └── firebase-debug.log # Created when CLI commands fail
12
+ ```
13
+ </project-structure>
14
+
15
+ ## Common Commands
16
+
17
+ <example>
18
+ ```bash
19
+ # Initialize new features
20
+ firebase init hosting
21
+ firebase init functions
22
+ firebase init firestore
23
+
24
+ # Deploy everything or specific services
25
+
26
+ firebase deploy
27
+ firebase deploy --only hosting
28
+ firebase deploy --only functions:processOrder,functions:sendEmail
29
+ firebase deploy --except functions
30
+
31
+ # Switch between projects
32
+
33
+ firebase use staging
34
+ firebase use production
35
+
36
+ ````
37
+ </example>
38
+
39
+ ## Local Development
40
+
41
+ <example>
42
+ ```bash
43
+ # Start all emulators
44
+ firebase emulators:start
45
+
46
+ # Start specific emulators
47
+ firebase emulators:start --only functions,firestore
48
+
49
+ # Common emulator URLs
50
+ # Emulator UI: http://localhost:4000
51
+ # Functions: http://localhost:5001
52
+ # Firestore: http://localhost:8080
53
+ # Hosting: http://localhost:5000
54
+ ````
55
+
56
+ </example>
57
+
58
+ ## Debugging Failed Commands
59
+
60
+ <example>
61
+ ```bash
62
+ # When any firebase command fails
63
+ cat firebase-debug.log # Contains detailed error traces
64
+
65
+ # Common fixes for errors in debug log
66
+
67
+ firebase login --reauth # Fix authentication errors
68
+ firebase use # Fix wrong project errors
69
+
70
+ ````
71
+ </example>
72
+
73
+ ## Complete Workflow Example
74
+
75
+ <example>
76
+ ```bash
77
+ # Clone and setup a Firebase project
78
+ git clone https://github.com/example/my-app
79
+ cd my-app
80
+
81
+ # Initialize Firebase in existing project
82
+ firebase init
83
+
84
+ # Start local development
85
+ firebase emulators:start
86
+
87
+ # Make changes, then deploy to staging
88
+ firebase use staging
89
+ firebase deploy
90
+
91
+ # Deploy to production
92
+ firebase use production
93
+ firebase deploy --only hosting,firestore
94
+ ````
95
+
96
+ </example>
97
+
98
+ ## Service Detection in firebase.json
99
+
100
+ <example>
101
+ ```json
102
+ {
103
+ "hosting": {
104
+ "public": "dist",
105
+ "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
106
+ },
107
+ "functions": {
108
+ "source": "functions",
109
+ "runtime": "nodejs20"
110
+ },
111
+ "firestore": {
112
+ "rules": "firestore.rules",
113
+ "indexes": "firestore.indexes.json"
114
+ },
115
+ "emulators": {
116
+ "functions": { "port": 5001 },
117
+ "firestore": { "port": 8080 },
118
+ "hosting": { "port": 5000 }
119
+ }
120
+ }
121
+ ```
122
+ </example>
@@ -0,0 +1,221 @@
1
+ # Firebase Functions Context (SDK 6.0.0+)
2
+
3
+ Always use v2 functions for new development. Use v1 only for Analytics, basic Auth, and Test Lab triggers.
4
+
5
+ For SDK versions before 6.0.0, add `/v2` to import paths (e.g., `firebase-functions/v2/https`).
6
+
7
+ ## Function Imports (SDK 6.0.0+)
8
+
9
+ <example>
10
+ ```typescript
11
+ // HTTPS functions
12
+ import {onRequest, onCall} from 'firebase-functions/https';
13
+
14
+ // Firestore triggers
15
+ import {onDocumentCreated, onDocumentUpdated, onDocumentDeleted} from 'firebase-functions/firestore';
16
+
17
+ // RTDB triggers
18
+ import {onValueCreated, onValueWritten, onValueUpdated, onValueDeleted} from 'firebase-functions/database';
19
+
20
+ // Scheduled functions
21
+ import {onSchedule} from 'firebase-functions/scheduler';
22
+
23
+ // Storage triggers
24
+ import {onObjectFinalized, onObjectDeleted} from 'firebase-functions/storage';
25
+
26
+ // Pub/Sub triggers
27
+ import {onMessagePublished} from 'firebase-functions/pubsub';
28
+
29
+ // Blocking Auth triggers
30
+ import {beforeUserCreated, beforeUserSignedIn} from 'firebase-functions/identity';
31
+
32
+ // Test Lab triggers
33
+ import {onTestMatrixCompleted} from 'firebase-functions/testLab';
34
+
35
+ // Deferred initialization
36
+ import {onInit} from 'firebase-functions';
37
+
38
+ // Structured logging
39
+ import {logger} from 'firebase-functions';
40
+
41
+ // Configuration
42
+ import {defineString, defineInt, defineSecret} from 'firebase-functions/params';
43
+ import * as params from 'firebase-functions/params';
44
+
45
+ // Note: For SDK versions before 6.0.0, add /v2 to import paths:
46
+ // import {onRequest} from 'firebase-functions/v2/https';
47
+
48
+ ````
49
+ </example>
50
+
51
+ ## v1 Functions (Analytics & Basic Auth Only)
52
+
53
+ <example>
54
+ ```typescript
55
+ // Use v1 ONLY for these triggers
56
+ import * as functionsV1 from 'firebase-functions/v1';
57
+ import {logger} from 'firebase-functions';
58
+
59
+ // Analytics triggers (v1 only)
60
+ export const onPurchase = functionsV1.analytics.event('purchase').onLog((event) => {
61
+ logger.info('Purchase event', {
62
+ value: event.params?.value,
63
+ currency: event.params?.currency
64
+ });
65
+ });
66
+
67
+ // Basic Auth triggers (v1 only)
68
+ export const onUserCreate = functionsV1.auth.user().onCreate((user) => {
69
+ logger.info('User created', { uid: user.uid, email: user.email });
70
+ // Initialize user profile...
71
+ });
72
+
73
+ export const onUserDelete = functionsV1.auth.user().onDelete((user) => {
74
+ logger.info('User deleted', { uid: user.uid });
75
+ // Cleanup user data...
76
+ });
77
+ ````
78
+
79
+ </example>
80
+
81
+ ## Environment Configuration
82
+
83
+ <example>
84
+ ```typescript
85
+ import {defineString, defineInt, defineSecret} from 'firebase-functions/params';
86
+ import * as params from 'firebase-functions/params';
87
+ import {onRequest} from 'firebase-functions/https';
88
+ import {logger} from 'firebase-functions';
89
+
90
+ // Built-in params available automatically
91
+ const projectId = params.projectID;
92
+ const databaseUrl = params.databaseURL;
93
+ const bucket = params.storageBucket;
94
+ const gcpProject = params.gcloudProject;
95
+
96
+ // Custom params
97
+ const apiUrl = defineString('API_URL', {
98
+ default: 'https://api.example.com'
99
+ });
100
+
101
+ const environment = defineString('ENVIRONMENT', {
102
+ default: 'dev'
103
+ });
104
+
105
+ const apiKey = defineSecret('STRIPE_KEY');
106
+
107
+ // Using params directly in runtime configuration
108
+ export const processPayment = onRequest({
109
+ secrets: [apiKey],
110
+ memory: defineString('PAYMENT_MEMORY', { default: '1GiB' }),
111
+ minInstances: environment.equals('production').thenElse(5, 0),
112
+ maxInstances: environment.equals('production').thenElse(1000, 10)
113
+ }, async (req, res) => {
114
+ logger.info('Processing payment', {
115
+ project: projectId.value(),
116
+ bucket: bucket.value(),
117
+ env: environment.value()
118
+ });
119
+
120
+ const key = apiKey.value();
121
+ const url = apiUrl.value();
122
+ // Process payment...
123
+ });
124
+
125
+ ````
126
+ </example>
127
+
128
+ ## Deferred Initialization
129
+
130
+ <example>
131
+ ```typescript
132
+ import {onInit} from 'firebase-functions';
133
+ import {onRequest} from 'firebase-functions/https';
134
+
135
+ let heavyClient: HeavySDK;
136
+
137
+ onInit(async () => {
138
+ const {HeavySDK} = await import('./lib/heavy-sdk');
139
+ heavyClient = new HeavySDK({
140
+ // Expensive initialization...
141
+ });
142
+ });
143
+
144
+ export const useHeavyClient = onRequest(async (req, res) => {
145
+ const result = await heavyClient.process(req.body);
146
+ res.json(result);
147
+ });
148
+ ````
149
+
150
+ </example>
151
+
152
+ ## Structured Logging
153
+
154
+ <example>
155
+ ```typescript
156
+ import {logger} from 'firebase-functions';
157
+ import {onRequest} from 'firebase-functions/https';
158
+
159
+ interface OrderRequest {
160
+ orderId: string;
161
+ userId: string;
162
+ amount: number;
163
+ }
164
+
165
+ export const processOrder = onRequest(async (req, res) => {
166
+ const {orderId, userId, amount} = req.body as OrderRequest;
167
+
168
+ logger.info("Processing order", {
169
+ orderId,
170
+ userId,
171
+ amount
172
+ });
173
+
174
+ try {
175
+ // Process...
176
+ logger.log("Order complete", { orderId });
177
+ res.json({ success: true });
178
+ } catch (error) {
179
+ logger.error("Order failed", {
180
+ orderId,
181
+ error: error instanceof Error ? error.message : 'Unknown error',
182
+ stack: error instanceof Error ? error.stack : undefined
183
+ });
184
+ res.status(500).json({ error: "Processing failed" });
185
+ }
186
+ });
187
+
188
+ ````
189
+ </example>
190
+
191
+ ## Development Commands
192
+
193
+ <example>
194
+ ```bash
195
+ # TypeScript development
196
+ cd functions
197
+ npm install
198
+ npm run build # Compile TypeScript
199
+
200
+ # Local development
201
+
202
+ firebase emulators:start --only functions
203
+
204
+ # Testing functions
205
+
206
+ npm test # Run unit tests
207
+ npm run serve # TypeScript watch + emulators
208
+
209
+ # Deployment
210
+
211
+ firebase deploy --only functions
212
+ firebase deploy --only functions:api,functions:onUserCreate
213
+
214
+ # Debugging
215
+
216
+ firebase functions:log
217
+ firebase functions:log --only api --lines=50
218
+
219
+ ````
220
+
221
+ </example>
@@ -0,0 +1,64 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "additionalProperties": false,
4
+ "definitions": {
5
+ "testConfig": {
6
+ "additionalProperties": false,
7
+ "type": "object",
8
+ "properties": {
9
+ "route": {
10
+ "type": "string",
11
+ "description": "URL route appended to the test target base URL at which to start the test"
12
+ }
13
+ }
14
+ },
15
+ "testStep": {
16
+ "additionalProperties": false,
17
+ "properties": {
18
+ "goal": {
19
+ "type": "string",
20
+ "description": "The goal of the test step"
21
+ },
22
+ "hint": {
23
+ "type": "string",
24
+ "description": "A hint to provide extra context to accomplish the goal"
25
+ },
26
+ "successCriteria": {
27
+ "type": "string",
28
+ "description": "Crtieria that the agent can use determine if the goal is complete"
29
+ }
30
+ }
31
+ },
32
+ "test": {
33
+ "additionalProperties": false,
34
+ "properties": {
35
+ "name": {
36
+ "type": "string",
37
+ "description": "A descriptive name of the test"
38
+ },
39
+ "testConfig": {
40
+ "$ref": "#/definitions/testConfig",
41
+ "description": "Configs to apply to the specific test"
42
+ },
43
+ "steps": {
44
+ "type": "array",
45
+ "items": {
46
+ "$ref": "#/definitions/testStep"
47
+ }
48
+ }
49
+ }
50
+ }
51
+ },
52
+ "properties": {
53
+ "defaultConfig": {
54
+ "$ref": "#/definitions/testConfig",
55
+ "description": "Default config to apply to each test within the file"
56
+ },
57
+ "tests": {
58
+ "type": "array",
59
+ "items": {
60
+ "$ref": "#/definitions/test"
61
+ }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: Firebase project development guidelines
3
+ globs:
4
+ - "firebase.json"
5
+ - "firestore.rules"
6
+ - "**/*.rules"
7
+ - "functions/**/*"
8
+ ---
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "firebase",
3
+ "version": "0.0.1",
4
+ "mcpServers": {
5
+ "firebase": {
6
+ "command": "npx",
7
+ "args": ["-y", "firebase-tools", "experimental:mcp", "--dir", "{{PROJECT_PATH}}"]
8
+ }
9
+ },
10
+ "contextFileName": "FIREBASE.md"
11
+ }
@@ -0,0 +1,6 @@
1
+ tests:
2
+ - testName: Smoke test
3
+ steps:
4
+ - goal: View the provided application
5
+ hint: No additional actions should be necessary
6
+ successCriteria: The application should load with no obvious errors