expo-image-picker and apollo-upload-client

16 views Asked by At

I want to create chat application with react native expo. I use the expo-image-picker to take a picture and upload it to my api graphql build with apollo. I use apollo-upload-client for uploading the picture but I see that the package doesn't support react native from this 18.0.0 version. I got Apollo error: response not successful: Received status code 400 when I try to upload

This is my apollo client instance:

import fetch from "cross-fetch";
import {
  ApolloClient,
  NormalizedCacheObject,
  InMemoryCache,
} from "@apollo/client";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { ApolloLink, HttpLink, split } from "@apollo/client/core";
import { getMainDefinition } from "@apollo/client/utilities";
import { createClient } from "graphql-ws";
import { AuthStorage } from "./utils/AuthStorage";
import createUploadLink from "apollo-upload-client/createUploadLink.mjs";

export const apolloClient = async (
  token?: string
): Promise<ApolloClient<NormalizedCacheObject>> => {
  const API_URI = process.env.EXPO_PUBLIC_API_URI;
  const API_URI_WS = process.env.EXPO_PUBLIC_URI_WS;

  const user = token ? token : (await AuthStorage.isAuth())?.token;
  const httpLink: HttpLink = new HttpLink({
    uri: API_URI,
    fetch,
    headers: {
      authorization: `Bearer ${user}`,
    },
  });

  const wsLink: GraphQLWsLink = new GraphQLWsLink(
    createClient({
      url: API_URI_WS as string,
      lazy: true,
      connectionParams: {
        authentication: `Bearer ${user}`,
      },
    })
  );

  const uploadLink = createUploadLink({
    uri: API_URI,
    fetch,
    headers: {
      authorization: `Bearer ${user}`,
    },
  });

  const splitLink = split(
    ({ query }) => {
      const definition = getMainDefinition(query);
      return (
        definition.kind === "OperationDefinition" &&
        definition.operation === "subscription"
      );
    },
    wsLink,
    httpLink
  );

  const link = ApolloLink.split(
    (operation) => {
      const definition = getMainDefinition(operation.query);
      return (
        definition.kind === "OperationDefinition" &&
        definition.operation === "mutation" &&
        !!definition.selectionSet?.selections.find(
          (selection) =>
            selection.kind === "Field" && selection.name.value === "upload"
        )
      );
    },
    uploadLink as any,
    splitLink
  );

  const client = new ApolloClient({
    link: link,
    cache: new InMemoryCache(),
  });

  return client;
};

And this is the mutation to upload image with messages:

export const SEND_MESSAGE_MOBILE = gql`
  mutation SendMessageDiscussGroupMobile(
    $discussionId: Float!
    $userId: Float!
    $messageInput: MessageInput!
    $data: [Upload!]
    $receiverId: Float
    $discussGroupId: Float
  ) {
    sendMessageDiscussGroupMobile(
      discussionId: $discussionId
      userId: $userId
      messageInput: $messageInput
      data: $data
      receiverId: $receiverId
      discussGroupId: $discussGroupId
    ) {
      theme
      createdAt
      updatedAt
      User {
        lastname
        firstname
        id
        photo
        status
      }
      Receiver {
        firstname
        lastname
        id
        photo
        status
      }
      DiscussGroup {
        groupName
        coverPhoto
        id
      }
      messages {
        id
        User {
          id
          lastname
          firstname
          photo
          status
        }
        content
        files {
          name
          extension
          url
          id
        }
        receiverId
        discussGroupId
        createdAt
        updatedAt
      }
      id
    }
  }
`;

This is the method to take picture and upload it:

const cameraPress = async () => {
    try {
      await requestCameraPermissionsAsync();
      let result = await launchCameraAsync({
        cameraType: CameraType.back,
        allowsEditing: false,
        aspect: [1, 1],
        quality: 1,
      });
      if (!result.canceled) {
        const reponse = await fetch(result.assets[0].uri);
        const blob = await reponse.blob();
        const file = new File([blob], result.assets[0].fileName as string, {
          type: result.assets[0].mimeType,
        });
        await sendMessage([file], message);
      }
    } catch (error) {
      console.log(error);
    }
  };
0

There are 0 answers