New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
馃悰 Bug Report: React Native File Upload #27
Comments
Thanks for reporting this! We're still trying to find a resource to replicate this problem and troubleshoot further. We'll report back when we have more info. |
@stnguyen90 here is the manual code it has
on ios it just creates a empty document with the file name note : need to change the api url
|
Finally I was able to solve the issue, thanks to @stnguyen90 for helping out the issue was with the form data handled by the sdk. here is my code and i have used custom form and XMLHttpRequest() to upload the images import { Button, Image, StyleSheet, Text, View } from "react-native";
import React, { useState } from "react";
import * as ImagePicker from "expo-image-picker";
import { Client, Account } from "appwrite";
import axios from "axios";
const client = new Client();
const API_URL = "https://demo.in/v1";
const PROJECT_ID = "62aa497432281eaabc7a";
const BUCKET_ID = "userImages";
client
.setEndpoint(API_URL) // We set the endpoint, change this if your using another endpoint URL.
.setProject(PROJECT_ID); // Your project ID
const account = new Account(client);
export default function App() {
const [image, setImage] = useState(null);
const [succ, setSucc] = useState(false);
const login = () => {
const promise = account.createEmailSession("demo@demo.com", "demodemo");
promise.then(
function (response) {
console.log(response); // Success
},
function (error) {
console.log(error); // Failure
}
);
};
function sendXmlHttpRequest(data) {
const xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
xhr.onreadystatechange = (e) => {
if (xhr.readyState !== 4) {
return;
}
console.log("xhr.status", xhr);
if (xhr.status === 201) {
resolve(JSON.parse(xhr.response));
} else {
reject("Request Failed");
}
};
xhr.open("POST", `${API_URL}/v1/storage/buckets/${BUCKET_ID}/files/`);
xhr.withCredentials = true;
// xhr.setRequestHeader("content-type", "multipart/form-data");
xhr.setRequestHeader("X-Appwrite-Project", PROJECT_ID);
xhr.setRequestHeader("X-Appwrite-Response-Format", "0.15.0");
xhr.setRequestHeader("x-sdk-version", "appwrite:web:9.0.1");
xhr.send(data);
});
}
const pickImage = async () => {
// No permissions request is necessary for launching the image library
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
setImage(result.uri);
}
};
const uploadImage = async () => {
let filename = image.split("/").pop();
// Infer the type of the image
let match = /\.(\w+)$/.exec(image);
let type = match ? `image/${match[1]}` : `image`;
console.log("_--------------------------------------_");
let formData = new FormData();
formData.append("fileId", "unique()");
formData.append("file", {
uri: image,
name: filename,
type,
});
// formData.append("read", "");
// formData.append("write", "");
console.log("formData", formData);
await sendXmlHttpRequest(formData).then(
function (response) {
console.log("response", response); // Success
setSucc(true);
},
function (error) {
console.log("error", error); // Failure
}
);
};
return (
<View style={styles.container}>
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Button onPress={login} title="login" />
<Button title="Pick an image from camera roll" onPress={pickImage} />
</View>
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
{image && (
<>
<Image
source={{ uri: image }}
style={{ width: 200, height: 200 }}
/>
<Button onPress={uploadImage} title="uploadImage" />
</>
)}
{succ && <Text style={{ fontSize: 32 }}>UPLOADED</Text>}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
}); |
this is still an issue... the solution above works - for files less than the chunk size of 5mb... any thing larger than that doesn't work... I've been looking into the module react-native-chunk-upload uploads chunks in the format *.tmp ... not sure if this is the reason why it doesn't work |
It's still an issue with the SDK but this is a version of the code above using the fetch api instead of building the XMLHttpRequest and it's working good for my case : fetch(`${API_URL}/v1/storage/buckets/${BUCKET_ID}/files/`, {
method: "POST",
headers: {
"content-type": "multipart/form-data",
"X-Appwrite-Project": PROJECT_ID,
"x-sdk-version": "appwrite:web:10.2.0",
},
body: formData,
credentials: "include",
}); |
I tried it and also react-native-background-upload. When it comes to a chunked upload, i get a response code of 400, but only with React Native. The same code in a React Website works. |
So, the crux of the problem with our SDK and react-native is FromData + File. In the browser, you can put a File into FormData and the browser will handle the multipart form request fine. React-Native, doesn't handle File the same way which is why you need to make formdata like: let formData = new FormData();
formData.append("fileId", "unique()");
formData.append("file", {
uri: image,
name: filename,
type,
}); Fyi, this is what react native expects a file to be: https://github.com/facebook/react-native/blob/17ecae9ce7bded79ab3a083c9d07e15460e5635c/packages/react-native/types/modules/globals.d.ts#L107 Now, we'd like to use the same SDK and for both browser and react-native and we'd like the signature to kind of be the same. I'm not sure what makes sense from the react-native side, though. How else are people getting files besides |
It's just file uri unless you want to convert it to a blob |
btw here is my updated code and it works fine for me
|
hi , this doesn't work for the new web sdk version, any solution on how to upload images ? |
I wish I could help but I migrated to supabase |
@rohankm We now have React Native SDK. Please check it out at https://github.com/appwrite/sdk-for-react-native |
馃憻 Reproduction steps
Im trying to upload files from react native expo
steps to reproduce
yarn create expo-app demo
cd demo
yarn add appwrite
here is my App.js
馃憤 Expected behavior
It should upload a file named filenamenew.txt to the specified bucket. The same works properly on react native web. but its not working in with android and ios
馃憥 Actual Behavior
Network request failed
at node_modules@babel\runtime\helpers\construct.js:19:9 in _construct
at node_modules@babel\runtime\helpers\wrapNativeSuper.js:26:22 in Wrapper
at http://192.168.0.108:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:120669:293 in _createSuperInternal
at node_modules\appwrite\dist\cjs\sdk.js:72:8 in AppwriteException#constructor
at node_modules\appwrite\dist\cjs\sdk.js:391:22 in __awaiter$argument_3
at node_modules@babel\runtime\helpers\regeneratorRuntime.js:86:13 in tryCatch
at node_modules@babel\runtime\helpers\regeneratorRuntime.js:66:31 in
at node_modules\appwrite\dist\cjs\sdk.js:25:46 in rejected
at node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
at node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:248:12 in _allocateCallback$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:112:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:162:14 in _callReactNativeMicrotasksPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:413:41 in callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:391:6 in __callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:133:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:368:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:132:4 in flushedQueue
馃幉 Appwrite version
Version 0.10.x
馃捇 Operating system
Windows
馃П Your Environment
No response
馃憖 Have you spent some time to check if this issue has been raised before?
馃彚 Have you read the Code of Conduct?
The text was updated successfully, but these errors were encountered: