How can you have both Authentication and Subscriptions with Apollo Client (React Native)

I’m pretty new to apollo and react native. I’m working on a project where I need to use graphql subscriptions and use graphql queries, which need authentication. From the apollo docs I had set-up my client.ts like:

import { ApolloClient, split, HttpLink, InMemoryCache } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";


const wslink = new GraphQLWsLink(
  createClient({
    url: "ws://localhost:4000/subscriptions",
  }),
);

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql'
});

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

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

but I need to add the authentication. The documents only mention authentication with this type of setup for the subscription aspect of the code:

const wslink = new GraphQLWsLink(
  createClient({
    url: "ws://localhost:4000/subscriptions",
    connectionParams: {
      authToken: user.authToken,
    },
  }),
);

which doesn’t help me and gives me an error because user is unknown. The apollo docs give:

import ApolloClient from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { ApolloLink, concat, split } from "apollo-link";
import { InMemoryCache } from "apollo-cache-inmemory";
import { getMainDefinition } from "apollo-utilities";

const httpLink = new HttpLink({ uri: process.env.VUE_APP_API_TARGET });

const authMiddleware = new ApolloLink((operation, forward) => {
  // add the authorization to the headers
const token = localStorage.getItem('token');
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : "",
    },
  });
  return forward(operation);
});
export const apolloClient = new ApolloClient({
  link: concat(authMiddleware, httpLink),
  cache: new InMemoryCache(),
});

as an example of how to add in the authentication aspect. What I’m having trouble with is how do you combine the two? Currently, I have:

import { ApolloClient, split, HttpLink, InMemoryCache } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { ApolloLink, concat} from "apollo-link";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";

const wslink = new GraphQLWsLink(
  createClient({
    url: "ws://localhost:4000/subscriptions",
  }),
);


const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql'
});

const authLink = new ApolloLink((operation, forward) => {
const token = /*await*/ AsyncStorage.getItem('token');
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : "",
    },
  });
  return forward(operation);
});

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

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

In export const client = new ApolloClient({cache: new InMemoryCache(), link: splitLink, });, I tried changing it to link: concat(authLink, splitLink), but that gives errors

"message": "Type 'ApolloLink' is missing the following properties from type 'ApolloLink': onError, setOnError",

and

"message": "Argument of type 'ApolloLink' is not assignable to parameter of type 'ApolloLink | RequestHandler'.\n  Type ... ApolloLink'.\n    Types of property 'split' are incompatible.\n     

I also tried replacing httpLink in const splitLink... with , but that gave the errors:

"message": "Argument of type 'ApolloLink' is not assignable to parameter of type 'ApolloLink | RequestHandler | undefined'.\n  Type 'ApolloLink' is missing the following properties from type 'ApolloLink': onError, setOnError",

and

"message": "Argument of type 'HttpLink' is not assignable to parameter of type 'ApolloLink | RequestHandler'.\n  Type 'HttpLink' is not assignable to type 'ApolloLink'.\n    Types of property 'split' are incompatible.\n...

Does anyone know how to do this? I would really appreciate any help or advice. Thank you!

I also ran into this problem, and I can’t find a solution. Author if you have found a solution, please share it.