Storage.put() throwing - AWSS3Provider - error uploading TypeError: Cannot read property 'byteLength' of undefined - vue.js

JavaScript Framework (Vue)
Amplify APIs (Storage)
Amplify Categories (storage)
Getting Cannot read property 'byteLength' of undefined while uploading media to s3 bucket using amplify storage, below is the code I am currently using
async onUpload(fileArr) {
if (fileArr.length > 0) {
console.log("fileArr", fileArr);
fileArr.map(async (obj) => {
try {
console.log({ Storage, Amplify });
console.log("Object =>", obj);
let baseData = await this.toBase64(obj);
console.log("Base Data =>", baseData);
const arrayBuffer = decode(baseData);
console.log("Array buffer =>", arrayBuffer);
let result = await Storage.put(
`hub/${obj.name}`,
arrayBuffer,
{
contentType: obj.type,
}
);
console.log("S3 Upload Result =>", result);
} catch (err) {
console.log("Error in uploading", err);
}
});
}
},
I tried to convert media to base64 before uploading but still getting same error
ERROR OUTPUT
Error - AWSS3Provider - error uploading TypeError: Cannot read property 'byteLength' of undefined
I granted full access to my IAM user and role but it didn't work either, I looked for multiple solution available online but still I didn't make it out.

I also faced this problem while uploading data to s3 using Apmplify.
The problem is not in your code its library version issue, make sure to use same Amplify version which is used on server
Latest Amplify version is 4.3.0
https://www.npmjs.com/package/aws-amplify

Related

Playing an audio file with source => {uri: 'remote-file-path'} not working - React Native (expo)

I keep getting this error when i try to play an audio from my local backend or an already uploaded audio from a site.
No matter what file format, this is what I get and this only happens with ios
error: Possible Unhandled Promise Rejection (id: 0): Error: The server is not correctly configured. - The AVPlayerItem instance has failed with the error code -11850 and domain "AVFoundationErrorDomain". Error: The server is not correctly configured. - The AVPlayerItem instance has failed with the error code -11850 and domain "AVFoundationErrorDomain".
error image
const player = new Audio.Sound();
player.loadAsync({ uri: url }, initialStatus).then(() => {
player.playAsync().then((playbackStatus) => {
if (playbackStatus.error) {
handlePlaybackError(playbackStatus.error);
}
});
});
After adding more error handling, I found out the error comes from loadAsync and it only happens when I try to play an audio from my local backend server. (ex: http://127.0.0.1:8000/media/audios/2021/08/08/27/21/filename.mp4)
It would be really great if I could get help on this, thanks in advance!
Update: Provided more code
So I found out that the that warning was being generated and preventing my audio files from playing because they are stored in my local server and for some reason the expo Audio.Sound object had an issue loading them, so I had to install expo-file-system, use the FileSystem to read download the file and use the uri produced from the download.
Example:
import * as FileSystem from 'expo-file-system';
const splitUrl = url.split('/');
const lastItem = splitUrl[splitUrl.length - 1];
const { uri } = await FileSystem.downloadAsync(
url,
FileSystem.documentDirectory + lastItem
);
const source = { uri: uri }; //the source you provide to the loadAsync() method
loadAsync() returns a Promise, so you have to await it.
If this is not the problem you have to provide more code, please.
Here's the documentation, so use it like this:
const sound = new Audio.Sound();
try {
await sound.loadAsync(require('./assets/sounds/hello.mp3'));
await sound.playAsync();
// Your sound is playing!
// Don't forget to unload the sound from memory
// when you are done using the Sound object
await sound.unloadAsync();
} catch (error) {
// An error occurred!
}
And here's a simple snack I made, it works for me, you might want to consider error handling using try-catch:
Snack example

React Native: Network error when using axios on local server

I'm new to react-native, I want to fetch some data from my local laravel server, but I fire the mobx action I get the following errors:
Network Error
[Unhandled promise rejection: Error: Network Error]
This is my mobx action (I'm using flow, similar to async/await), I get 'fire' log but after that I get the error above:
listProducts = flow( function*(payload)
{
console.log('fire');
try
{
let response = yield axios.get('http://192.168.1.39:8000/api/products', { params: payload });
this.posts = response.data;
this.pagination = response.data.pagination;
console.log(response);
//return response;
}
catch (error)
{
console.error(error);
throw error;
}
});
As you can see I'm using my local IP instead of localhost, I'm also testing my app on my android device using EXPO connected to the same network as my dev laptop.
Ciao, I can't see errors on your code. Try to follow this guide to handle Unhandled promise rejection. Could help you to find a clue.
In brief the guide suggest to use axios interceptors:
axios.interceptors.response.use(
response => response,
error => {}
)

Using AWS SDK (JS) for s3.selectObjectContent gives error on 'on' keyword

I'm using AWS SDK for Javascript version 2.730.0 (latest at time of writing) in a Typescript file in Node.JS.
I'm using the selectObjectContent operation to query a CSV file, and following the guide in the documentation I have this block:
import * as S3 from 'aws-sdk/clients/s3';
const s3 = new S3();
...
s3.selectObjectContent(params, (err, data) => {
if (!err){
data.Payload.on('data', (event) => {
// Do something with returned records
});
}
});
The line data.Payload.on('data', (event) => { is giving this error in the linter:
Property 'on' does not exist on type 'EventStream<{ Records?: RecordsEvent; Stats?: StatsEvent; Progress?: ProgressEvent; Cont?: ContinuationEvent; End?: EndEvent; }>'.
What do I need to change for on to work?
I ran into the same problem myself. Found this problem post on another forum:
https://www.gitmemory.com/issue/aws/aws-sdk-js/3525/725076849
It does not explicitly show code to solve the problem but based on the information, I solved it as follows:
import { ReadStream } from "fs";
const eventStream = data.Payload as ReadStream;
eventStream.on("data", ({ Records, Stats, Progress, Cont, End }: ...
TypeScript no longer complains.

React Native Uploading Video to YouTube (Stuck at Processing)

I am attempting to upload video files to YouTube using their v3 API and their MediaUploader. It works in my ReactJS application, but not in my React Native application. When uploading via React Native, the upload completes, then stalls at 100%. In my YouTube account, I can see the new video file, but it is stuck at "Video is still being processed."
I believe the issue may be that I need to send a video file and not an object with a video uri but I don't know how to get around that.
I am using the YouTube MediaUploader from the CORS example at https://github.com/youtube/api-samples/blob/master/javascript/cors_upload.js I am using an OAuth 2.0 client Id, and this setup works correctly when using the ReactJS app via my website. I am using React Native Expo with Camera, which returns me an Object with a URI, for example:
Video File: Object {
"uri": "file:///var/mobile/Containers/Data/Application/353A7969-E2A8-4C80-B641-C80B2B029555/Library/Caches/ExponentExperienceData/%2540dj_walksalot%252Fwandereo/Camera/E971DFEC-AB3E-4B6D-892F-9027AFE47A1A.mov",
}
This file can be viewed in the application, and I can even successfully send this to my server for playback on the web app and in the React Native app. However, sending this object in the MediaUploader does not work. It will take an appropriate amount of time to upload, but then sits at 100%, while my YouTube account will show it has received the video with the correct metadata, but the video itself remains stuck at "Video is still being processed."
video_file: Object {
"uri": "file:///var/mobile/Containers/Data/Application/353A7969-E2A8-4C80-B641-C80B2B029555/Library/Caches/ExponentExperienceData/%2540dj_walksalot%252Fwandereo/Camera/E971DFEC-AB3E-4B6D-892F-9027AFE47A1A.mov",
}
export const uploadToYouTube = (access_token, video_file, metadata) => async (dispatch) => {
...cors_upload...
var uploader = new MediaUploader({
baseUrl: `https://www.googleapis.com/upload/youtube/v3/videos?part=snippet%2Cstatus&key=API_KEY`,
file: video_file,
token: access_token,
metadata: metadata,
contentType: 'video/quicktime',
// contentType: 'application/octet-stream',//"video/*",
// contentType = options.contentType || this.file.type || 'application/octet-stream';
params: {
part: Object.keys(metadata).join(',')
},
onError: function(data) {
// onError code
let err = JSON.parse(data);
dispatch(returnErrors(err.message, err.code))
console.log('Error: ', err);
},
onProgress: function(progressEvent){
// onProgress code
let percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
dispatch({
type: UPLOAD_PROGRESS,
payload: percentCompleted
});
},
onComplete: function(data) {
console.log('Complete');
// onComplete code
let responseData = JSON.parse(data);
dispatch({
type: UPLOAD_YOUTUBE_VIDEO,
payload: JSON.parse(data)
})
dispatch({
type: UPLOAD_PROGRESS,
payload: 0
});
}
});
uploader.upload();
}
Similar to my currently-working web app, after completing the upload, the "onComplete" function should fire, and YouTube should process the video. This does not happen. I believe it's because I'm attaching an object with a URI and not the actual file.
I was able to solve this from a post at Expert Mill by Joe Edgar at https://www.expertmill.com/2018/10/19/using-and-uploading-dynamically-created-local-files-in-react-native-and-expo/
By using fetch and .blob() I was able to convert the URI object to a data object and upload. Additional code:
const file = await fetch(video_file.uri);
const file_blob = await file.blob();
No need to install RNFetchBlob since this is in the Expo SDK.

Input form provides File - how to I upload it to Azure Blob storage using Vue?

I'm clearly missing something here so forgive me - all examples seem to involve express and I don't have express in my setup. I am using Vue.js.
Ultimately, want my client-side Vue app to be able to upload any file to azure blob storage.
I have the file(File api) from my Vue form. However, it does not provide a path (I believe this is for security reasons). The Azure docs have this snippet example:
const uploadLocalFile = async (containerName, filePath) => {
return new Promise((resolve, reject) => {
const fullPath = path.resolve(filePath);
const blobName = path.basename(filePath);
blobService.createBlockBlobFromLocalFile(containerName, blobName, fullPath, err => {
if (err) {
reject(err);
} else {
resolve({ message: `Local file "${filePath}" is uploaded` });
}
});
});
};
Is this not the api I should be using? What should I be doing to upload any type of blob to blob storage?
UPDATE
Following #Adam Smith-MSFT comments below I have tried the vue-azure-storage-upload but can't seem to get the files up to azure.
startUpload () {
if (!this.files || !this.baseUrl) {
window.alert('Provide proper data first!')
} else {
this.files.forEach((file:File) => {
this.$azureUpload({
baseUrl: this.baseUrl + file.name,
sasToken: this.sasToken,
file: file,
progress: this.onProgress,
complete: this.onComplete,
error: this.onError
// blockSize
})
})
}
},
According to the console the response.data is undefined and when the onError method fires, that too gives me an undefined event.
I'd highly recommend checking the following tutorial: https://www.npmjs.com/package/vue-azure-blob-upload
The author used a specific npm package to upload blobs(you can using file service) to upload objects:
npm i --save vue-azure-blob-upload
I'd also recommend checking the Storage JS documentation: https://github.com/Azure/azure-storage-js/tree/master/file , it provides specific examples related to Azure File Storage as well.