Saud Punjwani
Saud Punjwani

Reputation: 517

Relay subscriptions not working with react-native

I'm using Express Graphql server with react native and Relay. My device does connects to the subscription but it does not subscribe to it. Here's my index.js on the server

const subscriptionServer = SubscriptionServer.create(
  {
    execute,
    subscribe,
    schema,
    onOperation: (message, params, webSocket) => {
      console.log(params)
      return params;
    },
    onConnect: () => {
      // My device does connects
      console.log("client connected")
    }
  },
  {
    server,
    path: '/subscriptions'
  },
);

app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true
}));

app.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
  subscriptionsEndpoint: `ws://127.0.0.1:8080/subscriptions`
}));

server.listen(PORT, ()=> {
  console.log("Groceries running on port " + PORT)
  console.log(
    `subscriptions is now running on ws://localhost:${PORT}/subscriptions'}`
  );
});

The resolver for subscription on the server, it was quite troublesome to figure out since everyone is using executable schema from apolloGraphql.

export default {
  type: OrderEdges,
  args: {
     ShopId: {type: GraphQLID},
  },
  subscribe: withFilter(() => pubsub.asyncIterator('orderConfirmed'), (payload, variables) => {
    console.log(payload)
    console.log(variables)
    return payload.orderConfirmed.node.ShopId == variables.ShopId;
  }),
}

Now the react-native client. My subscription setup with relay environment.

const setupSubscriptions = (config, variables, cacheConfig, observer) => {
  const query = config.text; //does console logs the query
  const subscriptionClient = new SubscriptionClient(`ws://192.168.0.100:8080/subscriptions`, {reconnect:true});
  subscriptionClient.request({query, variables}, (err, result) => {
    console.log(err) // doesn't get call inside the request method
    observer.onNext(data:result)
  })
}

My subscription method,

export default function() {
  const variables = {
    ShopId: shop.getShop()[0].id
  } 
  requestSubscription(
  environment,
  {
    subscription,
    variables,
    onCompleted: (res, err) => {
      console.log(res)
      console.log(err)
    },
    updater: (store) => {...},
    onError: error => console.error(error),
    onNext: (response) => {console.log(response)}
  });

}

the component where I'm calling to subscribe,

import subscription from '../../GraphQLQueries/subscriptions/orderConfirmed';

class OrdersBox extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    //initializing subscription
    orderSubscriptions();
  }

When the device starts the app, my device is connected to the web socket as I can see the console.log statement inside the onConnect method in SubscriptionServer. But when the payload is published after a mutation, the subscribe method doesn't get called. I can't seem to figure out what I'm doing wrong. Maybe it's some react-native specific config that I'm missing cuz everything seems to work fine when I test it on graphiql. I can't find any example of react-native and relay subscriptions used with express graphql.

note: Everything is working when I use subscription with graphiql. But not with react-native and relay.

Thanks in advance guys ....

Upvotes: 0

Views: 949

Answers (2)

Ng Thong
Ng Thong

Reputation: 104

try:

function setupSubscription(config, variables, cacheConfig, observer) {
  const query = config.text;

  const subscriptionClient = new SubscriptionClient(websocketURL, {
    reconnect: true
  });

  const client = subscriptionClient.request({ query, variables }).subscribe({
    next: result => {
      observer.onNext({ data: result.data });
    },
    complete: () => {
      observer.onCompleted();
    },
    error: error => {
      observer.onError(error);
    }
  });

  return {
    dispose: client.unsubscribe
  };
}

[email protected]

Upvotes: 0

Saud Punjwani
Saud Punjwani

Reputation: 517

I wasn't returning the subscriptionClient.request method. Adding a return statement solved the problem. You don't have to return when using subscribe method in [email protected]. But version 0.9.1 replaces the subscribe function with request which does require it to return.

Upvotes: 0

Related Questions