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);
}
};