Skip to content

Advanced

Uploads are automatically chunked and their state persisted to IndexedDB. If a transfer is interrupted, it can resume from the last successful chunk.

const manager = new FirebaseUploadManager({
chunkSize: 5 * 1024 * 1024, // 5MB chunks
enablePersistence: true
});
// Check for incomplete uploads from a previous session
const resumable = await manager.checkForResumableUpload(file);
if (resumable) {
console.log(`Can resume from ${resumable.uploadedBytes} bytes`);
}
// Resume all incomplete uploads
await manager.resumeIncompleteUploads();
  1. Files are split into chunks based on chunkSize
  2. Each chunk’s upload state is tracked individually
  3. State is persisted to IndexedDB after each chunk
  4. On resume, only unuploaded chunks are sent
  5. File integrity is verified via SHA hashing

The ConnectionMonitor tracks online/offline status and network quality.

import { ConnectionMonitor } from 'svelte-firebase-upload';
const monitor = new ConnectionMonitor();
monitor.isOnline; // boolean
monitor.connectionType; // 'wifi' | '4g' | '3g' | etc.
monitor.effectiveType; // '4g' | '3g' | '2g' | 'slow-2g'
monitor.onOnline(() => console.log('Back online'));
monitor.onOffline(() => console.log('Went offline'));
monitor.getNetworkQuality(); // 'excellent' | 'good' | 'poor' | 'unknown'
monitor.getRecommendedSettings(); // { maxConcurrent, chunkSize, timeout }
// Wait for connectivity
const connected = await monitor.waitForNetwork(5000); // 5s timeout
monitor.disconnect(); // Cleanup

The RetryHandler manages automatic retries with exponential backoff and jitter. It requires a ConnectionMonitor instance to adapt retry behavior based on network conditions.

import { ConnectionMonitor, RetryHandler } from 'svelte-firebase-upload';
const monitor = new ConnectionMonitor();
const retrier = new RetryHandler(monitor, {
maxAttempts: 3,
baseDelay: 1000, // 1 second
maxDelay: 30000, // 30 seconds cap
backoffMultiplier: 2,
jitter: true // Randomize delay to avoid thundering herd
});
const result = await retrier.retryWithBackoff(
() => uploadFile(file),
'upload-context'
);
// Cleanup when done
monitor.disconnect();

Control upload bandwidth to avoid saturating the user’s connection.

const manager = new FirebaseUploadManager({
maxBandwidthMbps: 10,
adaptiveBandwidth: true // Auto-adjust based on conditions
});
// Runtime control
manager.getBandwidthStats();
// { current, average, peak, limit, utilization }
import { BandwidthThrottle } from 'svelte-firebase-upload';
const throttle = new BandwidthThrottle({
maxBandwidthMbps: 10,
adaptiveBandwidth: true,
throttleInterval: 100 // ms between checks
});
await throttle.throttleUpload(chunkSize); // Waits if over limit
throttle.updateBandwidthUsage(bytesUploaded, timeMs);
throttle.getCurrentBandwidth(); // bytes/sec
throttle.getAverageBandwidth(); // bytes/sec
throttle.isWithinLimits(); // boolean
throttle.setBandwidthLimit(20); // Change limit at runtime
throttle.getRecommendedChunkSize();
throttle.pause();
throttle.resume();
throttle.destroy();

Run diagnostics before starting uploads to catch configuration issues early.

// Full health check
const health = await manager.performHealthCheck();
// {
// status: { healthy, issues[], networkStatus, permissionsValid },
// timestamp, duration,
// checks: { connection, storage, permissions, network, memory, bandwidth },
// details: { connectionLatency, storageQuota, ... }
// }
// Start only if healthy
const { canStart, healthResult } = await manager.startWithHealthCheck();
if (!canStart) {
console.error('Health check failed:', healthResult.status.issues);
}
// Quick status
manager.getHealthStatus();

Optimizes upload order based on file size and network conditions.

const manager = new FirebaseUploadManager({
enableSmartScheduling: true
});
// Toggle at runtime
manager.setSmartScheduling(true);
manager.isSmartSchedulingEnabled();
// Manual queue optimization
manager.optimizeQueue();

Firebase’s uploadBytesResumable retries CORS and network errors internally — it never fires the error callback, leaving uploads stuck at 0% forever. The library detects this automatically.

  • Connection timeout (8s): If zero bytes transfer within 8 seconds, the upload is cancelled and marked as failed. This catches CORS misconfigurations, wrong bucket names, and auth issues.
  • Stall timeout (30s): If progress was happening but stops for 30 seconds, the upload is cancelled. This catches dropped connections mid-upload.

The UploadPanel shows errors via:

  • Toast notifications — pop up above the panel with a friendly error message
  • Error banner — persistent red banner in the header showing failure count
  • Failed tab — per-file error messages with retry buttons
  • onerror callback — hook for custom error handling
<UploadPanel
uploadManager={manager}
onerror={(item, error) => {
// Custom error handling (e.g., send to error tracking)
reportError(`Upload failed: ${item.file.name}`, error);
}}
/>
ErrorMeaning
”Could not connect to Firebase Storage”CORS not configured, wrong bucket, or network blocked
”Connection lost during transfer”Upload was progressing but stalled for 30s+
“Firebase Storage not configured”setStorage() was not called before uploading
”Permission denied”Firebase Storage rules block the upload
”Storage quota exceeded”Bucket is full

File names are automatically sanitized when building storage paths:

  • Path traversal characters (../, ./) are stripped
  • Unsafe characters are replaced with underscores
  • A unique suffix is appended to prevent overwrites

My Photo (1).jpguploads/My_Photo__1__a3f8k2.jpg

The FileValidator performs deep security checks beyond MIME type validation:

  • File signature verification — checks magic bytes match the declared type
  • Executable detection — blocks .exe, .bat, .sh, etc.
  • Script content detection — scans for embedded scripts
  • Type masquerading — detects files pretending to be a different type
import { FileValidator } from 'svelte-firebase-upload';
const validator = new FileValidator();
const result = await validator.validateFile(file, {
maxSize: 50 * 1024 * 1024,
allowedTypes: ['image/*', 'application/pdf']
});
if (!result.valid) {
console.error(result.errors);
}
if (result.warnings.length) {
console.warn(result.warnings);
}
// File hash for deduplication
const hash = await validator.calculateFileHash(file, 'SHA-256');