How to Upload Files to Firebase Storage Using REST API Without NodeJS: Store Images, Audio in Folders (Avoid Base64 in Database)

Firebase Storage is a powerful, scalable solution for storing user-generated content like images, audio, and documents. While many developers use the Node.js SDK for integration, there are scenarios where you might need to interact with Firebase Storage directly via its REST API—for example, in non-JavaScript environments (Python, Java, Swift), legacy systems, or lightweight applications where adding a heavy SDK isn’t feasible.

This guide will walk you through uploading files to Firebase Storage using the REST API without Node.js. You’ll learn how to organize files into folders, support multiple file types (images, audio), and avoid the common pitfall of storing Base64-encoded files in your database (Firestore/Realtime Database). Instead, we’ll store file metadata and download URLs in the database, keeping your data efficient and scalable.

Table of Contents#

  1. Prerequisites
  2. Setting Up Your Firebase Project
    • 2.1 Creating a Firebase Project
    • 2.2 Enabling Firebase Storage
    • 2.3 Configuring Security Rules (Temporary)
    • 2.4 Getting Your Storage Bucket URL
  3. Understanding Firebase Storage REST API Fundamentals
    • 3.1 Base URL Structure
    • 3.2 Authentication Methods
    • 3.3 Key Endpoints
  4. Step-by-Step Implementation
    • 4.1 Obtaining an Authentication Token (Anonymous Auth)
    • 4.2 Creating Folders in Firebase Storage
    • 4.3 Uploading Files via REST API
      • 4.3.1 Uploading Images (JPG/PNG)
      • 4.3.2 Uploading Audio Files (MP3/WAV)
      • 4.3.3 Setting File Metadata (Content-Type)
    • 4.4 Saving Download URLs to a Database (Avoiding Base64)
  5. Retrieving Uploaded Files & Listing Folders
  6. Error Handling & Troubleshooting
  7. Best Practices for Production
  8. Conclusion
  9. References

Prerequisites#

Before you begin, ensure you have the following:

  • A Firebase account (free tier works for testing).
  • Basic familiarity with HTTP requests (GET, POST) and REST APIs.
  • A tool to send HTTP requests (e.g., Postman, curl, or programming language of choice like Python/Java).
  • A sample file to upload (e.g., an image: photo.jpg, an audio file: song.mp3).

Setting Up Your Firebase Project#

2.1 Creating a Firebase Project#

  1. Go to the Firebase Console.
  2. Click Add project, enter a name (e.g., "FileUploadDemo"), and follow the prompts to create the project.

2.2 Enabling Firebase Storage#

  1. In your Firebase project, navigate to Build > Storage.
  2. Click Get started, then select a location (e.g., "us-central1").
  3. Click Next and accept the default security rules (we’ll update them later).

2.3 Configuring Security Rules (Temporary)#

For testing, we’ll use open rules (not secure for production). Later, we’ll tighten them:

  1. In the Storage dashboard, go to the Rules tab.
  2. Replace the default rules with:
    rules_version = '2';  
    service firebase.storage {  
      match /b/{bucket}/o {  
        match /{allPaths=**} {  
          allow read, write: if true; // Open for testing  
        }  
      }  
    }  
  3. Click Publish.

2.4 Getting Your Storage Bucket URL#

Your Firebase Storage bucket URL is in the format:
https://firebasestorage.googleapis.com/v0/b/<bucket-name>.appspot.com/o
To find your bucket name:

  1. Go to Project settings (gear icon in the left nav).
  2. Under the General tab, scroll to Your apps and expand the "Web app" section (create one if needed).
  3. Look for storageBucket (e.g., myproject-12345.appspot.com).

Understanding Firebase Storage REST API Fundamentals#

Firebase Storage is built on Google Cloud Storage (GCS), but it provides a simplified REST API. Here’s what you need to know:

3.1 Base URL Structure#

Most Firebase Storage REST endpoints follow this pattern:

https://firebasestorage.googleapis.com/v0/b/<bucket-name>/o  
  • <bucket-name>: Your bucket (e.g., myproject-12345.appspot.com).

3.2 Authentication Methods#

To interact with Storage, you need to authenticate. Two common methods:

  • ID Token: For authenticated users (via Firebase Auth).
  • API Key: For unauthenticated access (only if rules allow it, not recommended for production).

We’ll use ID Tokens (via anonymous auth) for secure uploads.

3.3 Key Endpoints#

ActionEndpointMethod
Upload a filehttps://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<file-path>POST
List files in a folderhttps://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<folder>/GET
Get file metadatahttps://firebasestorage.googleapis.com/v0/b/<bucket>/o/<encoded-file-path>GET

Step-by-Step Implementation#

4.1 Obtaining an Authentication Token (Anonymous Auth)#

To upload files, we first need an ID token. We’ll use Firebase’s anonymous authentication to get one:

Request:#

  • URL: https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=<web-api-key>
  • Method: POST
  • Headers: Content-Type: application/json
  • Body:
    { "returnSecureToken": true }  

How to Get Your Web API Key:#

  1. Go to Project settings > General > Your apps > Web app.
  2. Copy the apiKey (e.g., AIzaSyD12345...).

Example with curl:#

curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyD12345..." \  
  -H "Content-Type: application/json" \  
  -d '{"returnSecureToken": true}'  

Response:#

You’ll get an idToken (use this for authentication):

{  
  "idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",  
  "expiresIn": "3600",  
  "localId": "abc123..."  
}  

4.2 Creating Folders in Firebase Storage#

Firebase Storage uses a "flat" namespace, but folders are simulated using file paths with slashes (e.g., images/photo.jpg). To create a folder:

  • Upload an empty file with a name ending in / (e.g., images/ for an "images" folder).

Example: Create an "images" folder#

Request:

  • URL: https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=images/
  • Method: POST
  • Headers:
    • Authorization: Bearer <idToken> (from Step 4.1)
    • Content-Type: multipart/form-data
  • Body: Empty file (no content).

curl Command:#

curl -X POST "https://firebasestorage.googleapis.com/v0/b/myproject-12345.appspot.com/o?name=images/" \  
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6..." \  
  -F "file="  # Empty file  

Response:#

{  
  "name": "images/",  
  "bucket": "myproject-12345.appspot.com",  
  "generation": "123456789",  
  "metageneration": "1",  
  "size": "0",  
  "contentType": "application/octet-stream",  
  "timeCreated": "2024-01-01T12:00:00.000Z",  
  "updated": "2024-01-01T12:00:00.000Z"  
}  

4.3 Uploading Files via REST API#

We’ll upload files using multipart/form-data to send binary data. The endpoint accepts the file and optional metadata.

4.3.1 Uploading Images (JPG/PNG)#

Let’s upload a JPG image to the images/ folder we created.

Request:

  • URL: https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=images/photo.jpg
  • Method: POST
  • Headers:
    • Authorization: Bearer <idToken>
    • Content-Type: multipart/form-data
  • Body: The image file (binary data).

curl Command:#

curl -X POST "https://firebasestorage.googleapis.com/v0/b/myproject-12345.appspot.com/o?name=images/photo.jpg" \  
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6..." \  
  -H "Content-Type: multipart/form-data" \  
  -F "file=@./photo.jpg;type=image/jpeg"  # Path to local image + content-type  

Response:#

{  
  "name": "images/photo.jpg",  
  "bucket": "myproject-12345.appspot.com",  
  "generation": "987654321",  
  "metageneration": "1",  
  "size": "204800",  # File size in bytes  
  "contentType": "image/jpeg",  
  "downloadTokens": "abc123def456...",  # Token for download URL  
  "timeCreated": "2024-01-01T12:05:00.000Z",  
  "updated": "2024-01-01T12:05:00.000Z"  
}  

The download URL is constructed as:

https://firebasestorage.googleapis.com/v0/b/<bucket>/o/images%2Fphoto.jpg?alt=media&token=<downloadTokens>  

(Note: %2F is the URL-encoded slash.)

4.3.2 Uploading Audio Files (MP3/WAV)#

Uploading audio is identical to images—just update the name and content-type:

Example: Upload song.mp3 to an audio/ folder

  1. First, create the audio/ folder (repeat Step 4.2 with name=audio/).
  2. Upload the audio file:
curl -X POST "https://firebasestorage.googleapis.com/v0/b/myproject-12345.appspot.com/o?name=audio/song.mp3" \  
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6..." \  
  -H "Content-Type: multipart/form-data" \  
  -F "file=@./song.mp3;type=audio/mpeg"  # audio/mpeg for MP3  

4.3.3 Setting File Metadata#

To ensure browsers/apps render files correctly, set the content-type explicitly (e.g., image/png, audio/wav). In the curl command, add ;type=<MIME-type> to the file field (as shown above).

4.4 Saving Download URLs to a Database (Avoiding Base64)#

Instead of storing Base64-encoded files in Firestore/Realtime Database (which bloats your database), save the download URL from the upload response.

Example: Save URL to Firestore via REST API#

Firestore’s REST endpoint for creating a document:

https://firestore.googleapis.com/v1/projects/<project-id>/databases/(default)/documents/files  

Request:

  • Method: POST
  • Headers:
    • Authorization: Bearer <idToken>
    • Content-Type: application/json
  • Body:
    {  
      "fields": {  
        "name": { "stringValue": "photo.jpg" },  
        "url": { "stringValue": "https://firebasestorage.googleapis.com/v0/b/..." },  
        "type": { "stringValue": "image" }  
      }  
    }  

Now your database stores lightweight URLs, not bulky Base64 data!

Retrieving Uploaded Files & Listing Folders#

List Files in a Folder#

To list all files in the images/ folder:

Request:

  • URL: https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=images/&delimiter=/
  • Method: GET
  • Headers: Authorization: Bearer <idToken>

Response:

{  
  "prefixes": [],  # Subfolders  
  "items": [  
    { "name": "images/photo.jpg", ... },  
    { "name": "images/other.png", ... }  
  ]  
}  

Access a File via Download URL#

Paste the download URL into a browser to view/download the file.

Error Handling & Troubleshooting#

Error CodeCommon CauseFix
403 ForbiddenInvalid/missing idToken or strict rulesRefresh token or adjust security rules
400 Bad RequestInvalid file path or missing name parameterCheck URL for typos; ensure name is set
413 Payload Too LargeFile exceeds Storage quota/size limitReduce file size or upgrade Firebase plan
404 Not FoundBucket doesn’t existVerify bucket name

Best Practices for Production#

  1. Secure Security Rules: Replace open rules with:
    allow read, write: if request.auth != null; // Require authentication  
  2. Validate File Types/Sizes: Check file extensions (e.g., .jpg, .mp3) and sizes client-side before upload.
  3. Sanitize File Names: Remove special characters to prevent path traversal (e.g., replace ../ with _).
  4. CORS Configuration: If uploading from a web app, allow your domain via CORS:
    # cors.json  
    [  
      {  
        "origin": ["https://yourapp.com"],  
        "method": ["POST", "GET"],  
        "maxAgeSeconds": 3600  
      }  
    ]  
    Upload with gsutil cors set cors.json gs://<bucket>.

Conclusion#

You now know how to upload files to Firebase Storage using the REST API—no Node.js required! By leveraging the REST API, you can integrate Firebase Storage into any environment, organize files into folders, and avoid Base64 bloat by storing download URLs in your database.

This approach is scalable, efficient, and works with any language or platform that supports HTTP requests.

References#