-
Notifications
You must be signed in to change notification settings - Fork 217
Open
Labels
Description
[REQUIRED] Environment info
firebase-functions: 6.4.0
firebase-tools: 14.16.0
Platform: macOS (Darwin 25.0.0)
[REQUIRED] Test case
import { onSchedule } from 'firebase-functions/v2/scheduler'
// This FAILS - creates scheduler with wrong URL format
export const failingScheduler = onSchedule(
'every 1 minutes',
async () => {
console.log('This function gets PERMISSION_DENIED')
}
)
// This WORKS - creates scheduler with correct URL
export const workingScheduler = onSchedule(
{
schedule: 'every 1 minutes',
timeZone: 'America/Los_Angeles',
},
async () => {
console.log('This function works correctly')
}
)
[REQUIRED] Steps to reproduce
- Create a v2 scheduled function using the string parameter syntax
- Deploy with
firebase deploy --only functions
- Check Cloud Scheduler console
- Observe the scheduler job has URL:
https://us-central1-PROJECT.cloudfunctions.net/FUNCTION_NAME
(v1 format) - Function execution fails with
PERMISSION_DENIED
[REQUIRED] Expected behavior
Both syntaxes should create Cloud Scheduler jobs with the correct v2 Cloud Run URLs (format: https://FUNCTION_NAME-HASH-uc.a.run.app/
)
[REQUIRED] Actual behavior
When using the string parameter syntax, Cloud Scheduler jobs are created with v1 function URLs that don't exist, causing PERMISSION_DENIED
errors.
Cloud Scheduler shows:
- Functions with string syntax: URL points to
cloudfunctions.net
(v1) - FAILS - Functions with object syntax: URL points to
run.app
(v2) - WORKS
Analysis
The TypeScript types allow both signatures:
onSchedule(schedule: string, handler: Function)
onSchedule(options: ScheduleOptions, handler: Function)
However, only the object syntax properly configures the Cloud Scheduler job with the correct Cloud Run URL. This is a critical bug because:
- The types suggest both are valid
- The deployment succeeds without warnings
- The error only appears at runtime when scheduler tries to invoke the function
- The error message (
PERMISSION_DENIED
) doesn't indicate the root cause is a URL mismatch
Workaround
Always use the object syntax with explicit schedule
and timeZone
properties:
onSchedule({
schedule: 'every 1 minutes',
timeZone: 'America/Los_Angeles',
}, handler)
Related Issues
This appears related to:
- cloud function error: PERMISSION_DENIED: Missing or insufficient permissions #1425 (PERMISSION_DENIED errors)
- Cloud Function V2 randomly not creating deterministic Function URL #1447 (Cloud Function V2 not creating deterministic Function URL)
- V2 scheduled functions do not refuse to deploy if the scheduler region is incompatible #1293 (V2 scheduled functions deployment issues)