pocketbase / js-sdk

PocketBase JavaScript SDK

Home Page:https://www.npmjs.com/package/pocketbase

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't upload files through react-native (using expo-image-picker)

saint-entity opened this issue · comments

I am making a react native application and I need to upload a file (specifically an Image) onto pocketbase through the app. However, pocketbase will upload the all the other information omitting the image. I have tried :

  • Uploading the image asset returned by expo-image-picker directly into pocketbase through the js-sdk in a dictionary
  • Uploading the image uri returned by expo-image-picker directly into pocketbase through the js-sdk in a dictionary
  • Uploading the image asset returned by expo-image-picker into a FormData into pocketbase through the js-sdk
  • Uploading the image uri returned by expo-image-picker into a FormData into pocketbase through the js-sdk
  • Using the image uri to fetch a blob from the file system to place in a dictionary to then upload to pocketbase
  • Using the image uri to fetch a blob from the file system to place in a FormData to then upload to pocketbase
  • Using the image uri to fetch a blob from the file system to place in a Javascript file object to place into a Dictionary/FormData to then upload to pocketbase
  • Using the image base64 to create a blob to place in a dictionary to then upload to pocketbase
  • Using the image base64 to create a blob to place in a Formdata to then upload to pocketbase
  • Using the image base64 to create a blob to place in a javascript file object to put in a dictionary to then upload to pocketbase
    const base64String = base64Data.startsWith("data:") ? base64Data.split(',')[1] : base64Data;
    const binaryString = decode(base64String);
    const uint8Array = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
        uint8Array[i] = binaryString.charCodeAt(i);
    }
    const blob = new Blob([uint8Array], { type: "image/jpeg" });
    return blob;
}


  async function ImageCreateData() {
    const pb = new PocketBase(ngrok);
    try {
      let formData = new FormData()

        

        const addy = await pb.collection('Addresses').getFirstListItem(`Address = '${address.Address}' && User = '["${userId}"]'`);
        
        const imagefile = base64toFile(image.base64)

        const imgdata = {
              "Image": new File([imagefile], 'image'),
              "Address": addy.id,
              "Caption": caption,
              "User": `["${userId}"]`
        }


        const imgrecord = await pb.collection('Images').create(imgdata);

        navigation.goBack()

    } catch (error) {
      console.log("Error creating tenant:", error);
      setError(true)
    }
  }```
This was my last attempt help will be appreciated greatly

What is the error that is returned? You can print the original error by doing something like console.log(error.originalError)

You can also start PocketBase with --debug and check for more detailed server error messages in the console.

One thing to note is that if you already have a Blob you don't need to wrap it to a File, aka. try to pass directly the Blob.

If that doesn't work, try to convert your imgdata to FormData because React Native/Expo seems to obfuscate the symbols and the internal instanceof checks doesn't work on all platforms:

const imgdata = new FormData();
imgdata.append("Image", imagefile);
imgdata.append("Address", caption);
...
const imgrecord = await pb.collection('Images').create(imgdata);

There were several discussion in the past for dealing with the file upload for React Native and Expo. This is not a PocketBase or JS SDK issue. We don't have any dependecies and use whatever global fetch is available. If you are not able to upload a file to PocketBase with fetch in React Native then you won't be able to do that with the SDK to. The issues come from the fact that the fetch implementation in React Native doesn't follow strictly the spec and has some small differences depending which platform you are targeting.

Please check pocketbase/pocketbase#2002 (comment)

Here is a minimal snack example - https://snack.expo.dev/D5LhGdXl9

I've tested it on Web and Android. Couple notes:

  • If you use ngrok, make sure to open the url first in the browser of the device you are testing because usually when you access the url for the first time on the device ngrok shows a splash screen where you have to click "Visit site" or similar.

  • If you get an API error double check your collections Create/Update API rules.

If you are still not able to make it work, please create a minimal snack expo example and export your collections configuration as json (Admin UI > Settings > Export collections) and I'll have a look at it.