A library that makes upload to AWS S3 bucket fasteasy, without any issues with missing file extension

AWS-S3-Upload-Library

A library that makes upload to AWS S3 bucket fasteasy, without any issues with missing file extension.

Follow the steps below:

Step 1: Login to AWS management console and go to S3:

  1. Create an s3 bucket

Step 2: Create identity pool:

  1. Search for cognito from the management console
  2. Click on federated entities
  3. Enable access to unauthenticated identities

Open federated entities to create a new identity pool

Click on create new identity pool

Enter your App name for identity pool name and enable access to unauthenticated identities and click on create pool.

Click on the Allow button to create two default roles associated with your identity pool: one for unauthenticated users and one for authenticated users

Your identity pool id will be shown to you in the code snippet copy and save for later.

Step 3: Grant permission to S3 bucket:

  1. Go to AWS IAM CONSOLE.
  2. Select Roles from the side menu.
  3. Search for Cognito_appnameUnath_Role
  4. Attach AmazonS3FullAccess policy to role

Search for Cognito_appnameUnath_Role replace app name with your Pool Id name

Select Unauth role and click on add permissions to reveal attach policy option, click on attach policy.

Search for AmazonS3FullAccess

Attach policy or permission

Step 4: Add the following dependencies to Android studio

  1. Add jitpack.io to your settings.gradle file

    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' } // add it here
    }
}
  1. Add the library dependency to app Gradle file.
implementation 'com.github.mavinomichael:AWS-S3-Upload-Library:1.0.1'

Step 5: Initialise S3Uploader object with the following details:

  1. Copy the cognito pool Id and region frommthe code snippet provided when creating the cognito pool which we saved earlier.

// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
    getApplicationContext(),
    "identity-pool-id", // copy Identity pool ID
    Regions.US_EAST_2 // copy Region
);
  1. Get your S3 bucket region by navigating to S3 click on buckets, select your bucket and click on properties.

(from the screenshot above the region for this bucket will be Regions.US_EAST_2).

  1. Copy the bucket name

  2. Initialise S3Uploader object like this:

Create a Kotlin object and add all the details copied above like this

object AWSKeys {
    const val COGNITO_POOL_ID = "cognito-pool-id"
    const val BUCKET_NAME = "bucket-name"
    val COGNITO_REGION = Regions.US_EAST_2
    val BUCKET_REGION = Regions.US_EAST_2
}

Reference the keys when creating the S3UploaderObject and call the uploadFile function.

val s3uploaderObj = S3Uploader(
            context,
            AWSKeys.BUCKET_NAME,
            AWSKeys.COGNITO_POOL_ID,
            AWSKeys.COGNITO_REGION,
            AWSKeys.BUCKET_REGION
        )
        
 //upload file to S3       
 fun uploadVideoTos3(videoUri: Uri, context: Context): String {
 
        //upload file with s3UploaderObject
        val fileUrl = s3uploaderObj.uploadFile(
            videoUri.path!!,
            "video/mp4",
            true
        )
        return fileUrl
     }

The uploadFile function returns the file URL from S3

  1. Set a listener for events during upload, like progress of upload, success, error, upload id, and state of upload.

s3uploaderObj.setOnUploadListener(object : S3UploadListener {
            override fun onSuccess(id: Int, response: String?) {
            
                Log.i(TAG, "viewModel status $response for uploadId: $id")
                
                if (response.equals("success", ignoreCase = true)) {
                   Log.i(TAG, "upload was successful with response: $response for uploadId: $id" 
                } else {
                    Log.i(TAG, "upload failed with response: $response")
                }
            }

            override fun onError(id: Int, response: String?) {
                Log.i(TAG, "viewModel error $response for uploadId: $id")
            }

            override fun onProgress(id: Int, progress: Int) {
                Log.i(TAG, "viewModel progress $progress for uploadId: $id")
            }

            override fun onStateChanged(
                id: Int,
                state: UploadState?
            ) {
                Log.d(TAG, "onStateChanged: $state")
            }

        })

Enjoy!

GitHub

View Github