This Firebase Storage error occurs when you pass an unsupported data type to the upload function. Firebase Storage upload methods accept only Blob, File, Uint8Array, or ArrayBuffer types. Passing strings, objects, or other data types will trigger this validation error. The fix is to ensure your data is converted to one of the supported formats before uploading.
The "storage/invalid-argument: Incorrect data type passed to upload function" error in Firebase Storage is a type validation failure. Firebase Storage upload functions like `uploadBytes()` and `uploadBytesResumable()` have strict type checking to ensure only binary data formats are uploaded. When you call an upload method, Firebase validates that the data parameter is one of the accepted types: Blob, File, Uint8Array, or ArrayBuffer. If you pass a string, JSON object, number, or any other unsupported type, Firebase immediately rejects the operation with this error. This validation prevents common programming mistakes where developers accidentally pass JavaScript objects or strings instead of binary data, which would result in corrupted or unusable files being stored in Cloud Storage. By catching this at the client side, Firebase helps you catch bugs before they reach the server.
The upload function accepts only File or Blob types from the JavaScript File API:
// CORRECT - File object from input element
const fileInput = document.getElementById('file-input');
const file = fileInput.files[0]; // This is a File object (subclass of Blob)
const storageRef = ref(storage, 'uploads/myfile.pdf');
await uploadBytes(storageRef, file); // File is accepted
// CORRECT - Blob object
const blob = new Blob(['file content'], { type: 'text/plain' });
await uploadBytes(storageRef, blob);
// WRONG - String data
const data = 'file content'; // This is a string, not a Blob
await uploadBytes(storageRef, data); // Error: Incorrect data type
// WRONG - JSON object
const jsonData = { name: 'John', age: 30 }; // Plain object
await uploadBytes(storageRef, jsonData); // Error: Incorrect data typeAlways get File objects from HTML file inputs or create Blob objects explicitly.
If you have string data that needs to be uploaded, convert it to a Blob:
// Convert string to Blob
const stringData = 'This is my file content';
const blob = new Blob([stringData], { type: 'text/plain' });
const storageRef = ref(storage, 'uploads/myfile.txt');
await uploadBytes(storageRef, blob);
// For JSON data
const jsonData = { name: 'John', age: 30 };
const jsonString = JSON.stringify(jsonData);
const jsonBlob = new Blob([jsonString], { type: 'application/json' });
const jsonRef = ref(storage, 'uploads/data.json');
await uploadBytes(jsonRef, jsonBlob);
// For CSV data
const csvString = 'name,age\nJohn,30\nJane,25';
const csvBlob = new Blob([csvString], { type: 'text/csv' });
const csvRef = ref(storage, 'uploads/data.csv');
await uploadBytes(csvRef, csvBlob);The Blob constructor takes an array of data and a MIME type. The type parameter helps Firebase and clients correctly identify the file format.
For base64 strings or other encoded formats, use the dedicated uploadString() method:
import { ref, uploadString } from 'firebase/storage';
// Upload base64 encoded image
const base64String = 'iVBORw0KGgoAAAANS...'; // Base64 encoded PNG
const storageRef = ref(storage, 'uploads/image.png');
await uploadString(storageRef, base64String, 'base64', {
contentType: 'image/png'
});
// Upload data URL (from canvas or camera)
const dataUrl = 'data:image/png;base64,iVBORw0KGgo...';
await uploadString(storageRef, dataUrl, 'data_url', {
contentType: 'image/png'
});
// Upload raw base64url format
const base64UrlString = 'iVBORw0KGgoAAAANS...'; // No padding
await uploadString(storageRef, base64UrlString, 'base64url', {
contentType: 'image/png'
});uploadString() handles string serialization and encoding automatically.
When fetching files from URLs, convert the response to a Blob:
// Fetch file from URL and upload
async function uploadFromUrl(url, storagePath) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch: ${response.statusText}`);
}
// Convert response to Blob - this is required!
const blob = await response.blob();
const storageRef = ref(storage, storagePath);
const result = await uploadBytes(storageRef, blob);
return result;
} catch (error) {
console.error('Upload failed:', error);
}
}
// Usage
uploadFromUrl('https://example.com/image.jpg', 'uploads/downloaded-image.jpg');
// Also works with response.arrayBuffer()
async function uploadFromUrlWithArrayBuffer(url, storagePath) {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const storageRef = ref(storage, storagePath);
await uploadBytes(storageRef, arrayBuffer); // ArrayBuffer is accepted
}Use response.blob() or response.arrayBuffer() to get compatible data types.
In Node.js environments, ensure file data is in the correct format:
const fs = require('fs');
const { getStorage, ref, uploadBytes } = require('firebase-admin/storage');
// CORRECT - Read file as Buffer
async function uploadFileFromDisk(filePath, storagePath) {
// fs.readFileSync returns a Buffer (compatible with uploadBytes)
const fileBuffer = fs.readFileSync(filePath);
const storage = getStorage();
const storageRef = ref(storage, storagePath);
// Buffer is accepted
await uploadBytes(storageRef, fileBuffer);
}
// CORRECT - Using promises
async function uploadFileFromDiskAsync(filePath, storagePath) {
const fileBuffer = await fs.promises.readFile(filePath);
const storage = getStorage();
const storageRef = ref(storage, storagePath);
await uploadBytes(storageRef, fileBuffer);
}
// WRONG - Reading as string
async function uploadFileWrong(filePath, storagePath) {
// readFileSync with encoding returns a string
const fileString = fs.readFileSync(filePath, 'utf-8'); // String - WRONG!
const storageRef = ref(storage, storagePath);
await uploadBytes(storageRef, fileString); // Error: Incorrect data type
}
// Convert string back to Buffer if needed
async function uploadFileFromString(fileContent, storagePath) {
// Convert string to Buffer
const fileBuffer = Buffer.from(fileContent, 'utf-8');
const storageRef = ref(storage, storagePath);
await uploadBytes(storageRef, fileBuffer); // Buffer is accepted
}In Node.js, Buffer objects are accepted by uploadBytes(). Never pass strings read from files.
File inputs automatically provide File objects in the correct format:
// HTML
<input type="file" id="fileInput" />
// JavaScript - File objects are ready to use
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0]; // File object (perfect for upload)
if (!file) {
console.error('No file selected');
return;
}
// Verify file type
console.log('File name:', file.name);
console.log('File size:', file.size);
console.log('File type:', file.type);
const storageRef = ref(storage, `uploads/${file.name}`);
try {
const result = await uploadBytes(storageRef, file);
console.log('Upload successful:', result);
} catch (error) {
console.error('Upload failed:', error);
}
});
// For multiple files
const fileInputMultiple = document.getElementById('fileInput');
fileInputMultiple.addEventListener('change', async (event) => {
for (const file of event.target.files) {
const storageRef = ref(storage, `uploads/${file.name}`);
await uploadBytes(storageRef, file);
}
});HTML file inputs provide properly typed File objects ready for uploading.
Use the correct Firebase method for your data format:
import { uploadBytes, uploadBytesResumable, uploadString } from 'firebase/storage';
const storageRef = ref(storage, 'uploads/file');
// uploadBytes() - for Blob, File, Uint8Array, ArrayBuffer
const file = new File(['content'], 'file.txt', { type: 'text/plain' });
await uploadBytes(storageRef, file); // Correct
// uploadBytesResumable() - same types as uploadBytes, with pause/resume
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed', ...); // Correct
// uploadString() - for string-based formats
const base64 = 'aGVsbG8gd29ybGQ='; // Base64 string
await uploadString(storageRef, base64, 'base64'); // Correct
// DO NOT mix methods with wrong data types
await uploadBytes(storageRef, 'string data'); // Error!
await uploadString(storageRef, someBlob); // Wrong method for BlobMatch your Firebase method to the data type you have.
### Supported Data Types in Firebase Storage
The upload functions have strict type requirements:
uploadBytes() and uploadBytesResumable():
- Blob - JavaScript Blob objects from File API
- File - File objects from input elements or File API
- Uint8Array - Typed array for binary data
- ArrayBuffer - Raw binary buffer
uploadString():
- string - Raw string, base64, base64url, or data URLs based on format parameter
### Blob vs File
File is a subclass of Blob, both are accepted by uploadBytes():
- Blob: Generic binary data container
- File: Blob with name and lastModified metadata from file system
### Type Checking in TypeScript
For TypeScript projects, use proper types:
import { ref, uploadBytes } from 'firebase/storage';
// Correctly typed function
async function uploadFileData(storage: Storage, file: File | Blob, path: string) {
const storageRef = ref(storage, path);
await uploadBytes(storageRef, file);
}
// This would be caught by TypeScript
async function uploadWrongType(storage: Storage, data: string, path: string) {
const storageRef = ref(storage, path);
await uploadBytes(storageRef, data); // TypeScript Error: string not assignable to Blob | File | Uint8Array | ArrayBuffer
}TypeScript can prevent this error at compile time.
### Common Type Conversion Patterns
String to Blob:
const blob = new Blob([string], { type: 'text/plain' });Base64 to Blob:
const binaryString = atob(base64String);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const blob = new Blob([bytes], { type: 'application/octet-stream' });JSON to Blob:
const blob = new Blob([JSON.stringify(object)], { type: 'application/json' });### Error Prevention Checklist
- Use TypeScript types to catch mismatches at compile time
- Extract files from HTML inputs directly (already correct type)
- Use appropriate method: uploadBytes for binary, uploadString for strings
- Verify MIME types for content-type metadata
- Test with real data before production deployment
- Use TypeScript strict mode to catch type errors early
- Add type guards in JavaScript for dynamic data
messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/missing-uid: User ID identifier required
How to fix "auth/missing-uid: User ID identifier required" in Firebase
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase