Read, download files
general considerations
-
The client SDK's functions are subject to access-control rules.
- Some functions allow the user, after access-control, to save a bearer URL which is not subject to security rules. This pattern is a one-off access control.
-
Download workflows are influenced by the browser restrictions regarding the file's URL.
get a HTTP URL on the client
We request a read URL. Access control is performed during such request.
The returned URL is a bearer URL, which is not subject to access-control. We consume it as a regular URL, outside the realm and control of the Storage SDK.
Note: the URL remains valid unless manually revoked at the file level in the Firebase Console, or with the admin SDK.
getDownloadURL(fileRef).then(url => ...)
consume a cross-origin HTTP URL on the client (browser-specific)
The bucket's file lives on a separate origin than the origin that ships the web-app. For the browser, the file's URL is cross-origin. The challenges and patterns to consume a cross-origin URL are not specific to Firebase.
The way we consume the URL determines if CORS headers are necessary:
- The browser allows cross-origin URLs in media elements' src attribute (hot linking), with no CORS header requirement.
- The browser allows navigating to cross-origin URLs (basic browser behavior). For example, we navigate to an image in a new tab.
- The browser doesn't allow background fetch of cross-origin resources unless explicit CORS headers are present on the server. This applies to fetch() and functions that rely on it.
Buckets do not have permissive CORS headers by default, but we can add them on demand. CORS headers whitelist one, several or all domains. We use gcloud to whitelist our domain (see the dedicated CORS chapter).
download a Blob with the client SDK
A blob is an opaque object that we fetch and transform to a local URL for easier saving. When using getBlob():
- access rules are enforced
- CORS headers are required (it uses fetch() under the hood)
We create a local (same-origin) URL out of the blob, to avoid the browser restrictions against cross-origin URLs. It restores the ability to download content through a single click, without navigating to a different URL (see below).
getBlob(fileRef).then((blob) => {
// create a local URL and trigger download imperatively
})
add the download attribute to an anchor tag with a local URL
The download attribute on anchor tags (<a href="" download>) offers one-click downloads for same-origin URLs or local URLs.
For cross-origin URLs, clicking the anchor tag triggers standard browser navigation instead: the browser navigates to the resource and shows its full URL.
create a local URL out of a blob (browser specific)
This example also triggers download programmatically, and revokes the local URL for clean up. We set the user-facing file name by setting the download attribute:
// 3. Create a local URL out of the blob
const objectURL = URL.createObjectURL(blob)
// 4. Use the local URL and trigger the download
const link = document.createElement("a")
link.href = objectURL
link.download = img.id + ".png"
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
// 5. Clean up by revoking the local URL
URL.revokeObjectURL(objectURL)