1

I am currently trying to upload a file (an image from RNCamera) from a react native android app to a GraphQL backend. However, the backend always returns status code 400.

So far, I have tried using another query that only requires a string (instead of the $file argument) and that worked. So the Apollo Client seems to be set up correctly. I have also tried sending files to the backend using curl. That worked fine as well.

import { API_URL } from 'src/utils/config';    
import { ApolloClient, InMemoryCache, ApolloLink, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
import { UPLOAD_PICTURE } from 'src/utils/query';

var RNFS = require('react-native-fs');

// Instantiate required constructor fields
const cache = new InMemoryCache();
const link = ApolloLink.from([
  createUploadLink({
    uri: API_URL
  })
]);

const client = new ApolloClient({
  // Provide required constructor fields
  cache: cache,
  link: link
});

Executing the mutation:

// read the image that was saved as a file
const file = {
    file: await RNFS.readFile(action.picture.uri, 'base64')
  };

// send the file to the backend
 client
    .mutate({
      mutation: gql(UPLOAD_PICTURE),
      variables: file
    })

From src/utils/query:

export const UPLOAD_PICTURE = `
mutation ($file: Upload!){
  uploadFile(file: $file)
}
`;

The GraphQL schema in the backend:

type File {
    uri: String!
    filename: String!
    mimetype: String!
    encoding: String!
  }

//...

type Mutation {
  //...
  uploadFile(file: Upload!): File
}
2
  • 1st - test backend with postman, 2nd, send a file, not content/stream etc ... compare network request with postman Commented Aug 14, 2020 at 16:14
  • Thank you for the feedback. A tool that really helped me while testing was the React Native Debugger with the "Network Inspect" option enabled. I found a solution for my problem (see below). Commented Aug 16, 2020 at 5:37

1 Answer 1

2

I found the solution to my problem. The file has to be of type ReactNativeFile (more info here). The code now looks like this:

...    
const file = new ReactNativeFile({
        uri: action.picture.uri,
        name: 'name.jpg',
        type: 'image/jpeg'
    });
...

There was also a bug with React Native 0.62+ that messes up the configuration for multiform requests. It can be fixed by commenting out line 43 in android/app/src/debug/java/com/maxyride/app/drivers/ReactNativeFlipper.java:

//builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.