[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:
[REQUIRED] Environment info
firebase-functions: 6.4.0
firebase-tools: 14.16.0
Platform: macOS (Darwin 25.0.0)
[REQUIRED] Test case
[REQUIRED] Steps to reproduce
firebase deploy --only functionshttps://us-central1-PROJECT.cloudfunctions.net/FUNCTION_NAME(v1 format)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_DENIEDerrors.Cloud Scheduler shows:
cloudfunctions.net(v1) - FAILSrun.app(v2) - WORKSAnalysis
The TypeScript types allow both signatures:
However, only the object syntax properly configures the Cloud Scheduler job with the correct Cloud Run URL. This is a critical bug because:
PERMISSION_DENIED) doesn't indicate the root cause is a URL mismatchWorkaround
Always use the object syntax with explicit
scheduleandtimeZoneproperties:Related Issues
This appears related to: