FireLogGet the app

Firebase Hosting and Cloud Storage: Where Your Files Live

Hosting serves the files you wrote. Storage holds the files your users send you. Mixing them up is the most common mistake here.

9 min read · updated August 5, 2026

Firebase gives you two places to keep files, with names similar enough that people reach for the wrong one. The distinction is simple once stated:

Firebase HostingCloud Storage for Firebase
HoldsFiles you wroteFiles your users upload
ExamplesHTML, CSS, JavaScript, images in your buildProfile photos, PDFs, video
Who can writeOnly you, at deploy timeYour users, at any time
Access controlPublic — it is a websiteSecurity rules, per file
Served fromA global CDNA Google Cloud Storage bucket

Rule of thumb: if the file exists on your laptop before you deploy, it belongs in Hosting. If it arrives from a phone at three in the morning, it belongs in Storage.

Firebase Hosting

Hosting serves your website from a global CDN with HTTPS switched on by default. You do not configure a certificate, a server, or a cache.

Deploying is two commands:

npm install -g firebase-tools
firebase login

firebase init hosting   # asks which folder holds your built site
firebase deploy

That is the whole workflow. The folder you point it at — dist, build, out, whatever your framework produces — is uploaded and served worldwide.

Preview channels are the underused feature

One command gives you a temporary URL with your changes on it, live, without touching production:

firebase hosting:channel:deploy pr-142 --expires 7d

The URL expires by itself. This is genuinely useful for showing work to someone before it ships, and it costs nothing extra.

Static sites versus server-rendered ones

Classic Firebase Hosting serves static files. If your framework produces HTML at build time — Vite, Create React App, a static Next.js export, plain HTML — it fits perfectly.

If your app renders on the server for every request, static hosting alone cannot run it. There are two routes:

Cloud Storage for Firebase

Storage is where user files go. It sits on top of Google Cloud Storage, so the files are in a real GCS bucket you can also reach with Google Cloud tooling.

Uploading from a browser or app:

import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";

const storage = getStorage();

// Scope the path by user id so security rules can check ownership.
const fileRef = ref(storage, `avatars/${userId}/profile.jpg`);

await uploadBytes(fileRef, file);
const url = await getDownloadURL(fileRef);

Note the path. Putting the user's ID in it is what makes the security rule below possible — you cannot write a rule about ownership if the path does not encode who owns the file.

Storage security rules

Storage has its own rules, separate from Firestore's. They are the only thing standing between your bucket and the internet.

rules_version = "2";
service firebase.storage {
  match /b/{bucket}/o {

    match /avatars/{userId}/{fileName} {
      // Anyone signed in can look at an avatar.
      allow read: if request.auth != null;

      // Only the owner can upload, and only images under 5MB.
      allow write: if request.auth != null
                   && request.auth.uid == userId
                   && request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches("image/.*");
    }
  }
}

getDownloadURL() returns a URL containing a token. That URL works for anyone who has it, regardless of your security rules, until you revoke the token.

This is convenient and occasionally a leak. If a file must stay private, do not pass its download URL around — have the client read it through the SDK, where rules are enforced every time.

What each costs

Both bill for stored bytes and transferred bytes, with a monthly free allowance. Storage also counts operations — uploads, downloads, deletes.

The expensive pattern is serving large media to many people. A popular video streamed from Cloud Storage is pure egress, and egress is the line item that grows. At that point a dedicated media CDN is usually cheaper.

Frequently asked questions

What is the difference between Firebase Hosting and Cloud Storage?
Hosting serves the files you deploy — your website. Cloud Storage holds files your users upload, protected by security rules. Hosting is public by design; Storage is not.
Can I host a Next.js app on Firebase Hosting?
A fully static export, yes. If your app uses server components, API routes or server-side rendering, plain Hosting cannot run it — use Firebase App Hosting, or rewrite dynamic routes to a Cloud Function.
Is Firebase Hosting free?
There is a monthly free allowance for stored data and transfer, which is enough for a small site. Beyond it you pay per gigabyte on the Blaze plan.
How do I deploy to Firebase Hosting?
Install firebase-tools, run `firebase init hosting` and point it at your build output folder, then run `firebase deploy`. Preview channels let you deploy to a temporary URL instead.
Are Firebase Storage download URLs private?
No. A download URL contains a token and works for anyone holding the link, whatever your security rules say, until the token is revoked. For genuinely private files, read through the SDK so rules are checked each time.
How do I limit upload file size in Firebase Storage?
In your Storage security rules, check `request.resource.size` on write. Checking `request.resource.contentType` at the same time stops people uploading the wrong kind of file entirely.

Keep reading