Skip to content

Native file upload, upload native file directly in native layer

License

Notifications You must be signed in to change notification settings

Cap-go/capacitor-uploader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@capgo/capacitor-uploader

Capgo - Instant updates for capacitor

Uploader Plugin

This plugin provides a flexible way to upload natively files to various servers, including S3 with presigned URLs.

Can be used in combination with the Capacitor Camera preview To upload file in reliable manner instead of reading them in buffer of webview and then upload in JS.

Install

npm install @capgo/capacitor-uploader
npx cap sync

Android:

Add the following to your AndroidManifest.xml file:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Exemple S3 upload:

Example S3 upload:

import { Uploader } from '@capgo/capacitor-uploader';

async function uploadToS3(filePath: string, presignedUrl: string, fields: Record<string, string>) {
  try {
    const { id } = await Uploader.startUpload({
      filePath: filePath,
      serverUrl: presignedUrl,
      method: 'PUT',
      parameters: fields,
      notificationTitle: 'Uploading to S3'
    });

    console.log('Upload started with ID:', id);

    // Listen for upload events
    Uploader.addListener('events', (event: UploadEvent) => {
      if (event.name === 'uploading') {
        console.log(`Upload progress: ${event.payload.percent}%`);
      } else if (event.name === 'completed') {
        console.log('Upload completed successfully');
      } else if (event.name === 'failed') {
        console.error('Upload failed:', event.payload.error);
      }
    });

  } catch (error) {
    console.error('Failed to start upload:', error);
  }
}

Exemple upload to a custom server:

import { Uploader } from '@capgo/capacitor-uploader';

async function uploadToCustomServer(filePath: string, serverUrl: string) {
  try {
    // Start the upload
    const { id } = await Uploader.startUpload({
      filePath: filePath,
      serverUrl: serverUrl,
      method: 'POST',
      headers: {
        'Authorization': 'Bearer your-auth-token-here'
      },
      parameters: {
        'user_id': '12345',
        'file_type': 'image'
      },
      notificationTitle: 'Uploading to Custom Server',
      maxRetries: 3
    });

    console.log('Upload started with ID:', id);

    // Listen for upload events
    Uploader.addListener('events', (event) => {
      switch (event.name) {
        case 'uploading':
          console.log(`Upload progress: ${event.payload.percent}%`);
          break;
        case 'completed':
          console.log('Upload completed successfully');
          console.log('Server response status code:', event.payload.statusCode);
          break;
        case 'failed':
          console.error('Upload failed:', event.payload.error);
          break;
      }
    });

    // Optional: Remove the upload if needed
    // await Uploader.removeUpload({ id: id });

  } catch (error) {
    console.error('Failed to start upload:', error);
  }
}

// Usage
const filePath = 'file:///path/to/your/file.jpg';
const serverUrl = 'https://your-custom-server.com/upload';
uploadToCustomServer(filePath, serverUrl);

Exemple with Capacitor Camera preview:

Documentation for the Capacitor Camera preview

  import { CameraPreview } from '@capgo/camera-preview'
  import { Uploader } from '@capgo/capacitor-uploader';


  async function record() {
    await CameraPreview.startRecordVideo({ storeToFile: true })
    await new Promise(resolve => setTimeout(resolve, 5000))
    const fileUrl = await CameraPreview.stopRecordVideo()
    console.log(fileUrl.videoFilePath)
    await uploadVideo(fileUrl.videoFilePath)
  }

  async function uploadVideo(filePath: string) {
    Uploader.addListener('events', (event) => {
      switch (event.name) {
        case 'uploading':
          console.log(`Upload progress: ${event.payload.percent}%`);
          break;
        case 'completed':
          console.log('Upload completed successfully');
          console.log('Server response status code:', event.payload.statusCode);
          break;
        case 'failed':
          console.error('Upload failed:', event.payload.error);
          break;
      }
    });
    try {
      const result = await Uploader.startUpload({
        filePath,
        serverUrl: 'S#_PRESIGNED_URL',
        method: 'PUT',
        headers: {
          'Content-Type': 'video/mp4',
        },
        mimeType: 'video/mp4',
      });
      console.log('Video uploaded successfully:', result.id);
    } catch (error) {
      console.error('Error uploading video:', error);
      throw error;
    }
  }

API

startUpload(...)

startUpload(options: uploadOption) => Promise<{ id: string; }>
Param Type Description
options uploadOption uploadOption

Returns: Promise<{ id: string; }>

Since: 0.0.1


removeUpload(...)

removeUpload(options: { id: string; }) => Promise<void>
Param Type
options { id: string; }

Since: 0.0.1


addListener('events', ...)

addListener(eventName: "events", listenerFunc: (state: UploadEvent) => void) => Promise<PluginListenerHandle>
Param Type
eventName 'events'
listenerFunc (state: UploadEvent) => void

Returns: Promise<PluginListenerHandle>

Since: 0.0.1


Interfaces

uploadOption

Prop Type Default Since
filePath string 0.0.1
serverUrl string 0.0.1
notificationTitle number 'Uploading' 0.0.1
headers { [key: string]: string; } 0.0.1
method 'PUT' | 'POST' 'POST' 0.0.1
mimeType string 0.0.1
parameters { [key: string]: string; } 0.0.1
maxRetries number 0.0.1

PluginListenerHandle

Prop Type
remove () => Promise<void>

UploadEvent

Prop Type Description Default Since
name 'uploading' | 'completed' | 'failed' Current status of upload, between 0 and 100. 0.0.1
payload { percent?: number; error?: string; statusCode?: number; } { percent: 0, error: '', statusCode: 0 } 0.0.1
id string 0.0.1

Credits:

For the inspiration and the code on ios: https://github.com/Vydia/react-native-background-upload/tree/master For the API definition: https://www.npmjs.com/package/cordova-plugin-background-upload-put-s3