Skip to content

Storage InstanceCache keys by bucket only, ignoring FirebaseApp. Causes auth failure for named apps sharing a bucket #16039

@llamington

Description

@llamington

Description

Expected behavior: When calling getDownloadURL() on a storage reference created from a named (non-default) Firebase app, the request should include the Authorization header from that app's authenticated user.

Actual behavior: The request is sent without an Authorization header, resulting in StorageErrorCode.unauthorized. This happens because the InstanceCache in Storage.swift caches Storage instances keyed by bucket name only, ignoring the FirebaseApp. When a named app shares the same storage bucket as the [DEFAULT] app, the cached [DEFAULT] instance is returned — carrying the wrong (or empty) AuthInterop.

Reproducing the issue

  1. Have a GoogleService-Info.plist that creates a [DEFAULT] app for project my-project with storageBucket: "my-project.appspot.com". Do not sign in on the default app.

  2. Dynamically initialize a named app pointing to the same project:

let options = FirebaseOptions(/* same project credentials */)
options.storageBucket = "my-project.appspot.com"
FirebaseApp.configure(name: "my-named-app", options: options)
  1. Sign in on the named app:
Auth.auth(app: FirebaseApp.app(name: "my-named-app")!).signIn(withCustomToken: token)
  1. Confirm auth works — Auth.auth(app:).currentUser is non-null with correct claims.

  2. Attempt to get a download URL via the named app:

let storage = Storage.storage(app: FirebaseApp.app(name: "my-named-app")!, url: "gs://my-project.appspot.com")
let ref = storage.reference(withPath: "some/file.png")
ref.downloadURL { url, error in
    // error: StorageErrorCode.unauthorized
}
  1. The same request succeeds when made manually via URLSession with an explicit Authorization: Bearer <token> header.

Firebase SDK Version

11.x (current main branch)

Xcode Version

26.x

Installation Method

CocoaPods

Firebase Product(s)

Storage

Targeted Platforms

iOS

Relevant Log Output

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet
Replace this line with the contents of your Package.resolved.

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
Replace this line with the contents of your Podfile.lock!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions