When I connect more clients on Apollo React only the last client receive GraphQL Subscriptions updates

259 Views Asked by At

Basically, when there is more than one client connected, only the last client connected receives GraphQL subscriptions data through the web socket.

This doesn't happen with old React classes, it happens only when I use stateless functions through Apollo Hooks Provider. I tried several methods already, such as subscribeToMore (that was working perfectly with classes) or useSubscription and in general everything that is suggested on this page https://www.apollographql.com/docs/react/data/subscriptions/.

These are the relevant parts of the component code, the subscribeToMore part is basically copy-pasted from an old React class where it works perfectly on the same project.

(If there are missing functions or variables, it's just because I avoided to post a lot of clutter, the code has been tested and runs with no error except for the subscriptions problem)

import React, { useEffect, useState } from 'react';
import { compose } from 'redux';
// other imports

function CommentsPanel(props) {
  const { loading, documentComments: comments } = commentsQuery;
  const [subscribed, setSubscribed] = useState(false);
  useEffect(() => {
    if (loading || comments == null || subscribed) return;
    console.log(commentsQuery);
    commentsQuery.subscribeToMore({
      document: ON_COMMENT_ADDED,
      variables: {
        documentId: projectId,
        userId: Meteor.userId(),
      },
      updateQuery: (previousResult, { subscriptionData }) => {
        console.log('On comment added subscription');
        return {
          ...previousResult,
          documentComments: [
            subscriptionData.data.commentAdded,
            ...previousResult.documentComments,
          ],
        };
      },
    });
    // other similar subscriptions
    setSubscribed(true);
  }, [loading, comments, subscribed, commentsQuery, projectId]);


     //render and a bunch of other stuff

export default compose(
  graphql(DOCUMENT_COMMENTS, {
    name: 'commentsQuery',
    options: ({ projectId }) => ({
      variables: {
        documentId: projectId,
      },
    }),
  }),
  withStyles(styles),
)(CommentsPanel);


And this is the client

import React from 'react';
import 'babel-polyfill';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { hydrate } from 'react-dom';
import { BrowserRouter, Switch } from 'react-router-dom';
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
import { ApolloProvider } from 'react-apollo';
import { ApolloProvider as ApolloHooksProvider } from '@apollo/react-hooks';
import { Accounts } from 'meteor/accounts-base';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import CssBaseline from '@material-ui/core/CssBaseline/CssBaseline';
import reducerApp from '../../reducers';
import apolloClient from './apollo';
import App from '../../ui/layouts/App';
import theme from '../theme';

Bert.defaults.style = 'growl-bottom-right';

Accounts.onLogout(() => apolloClient.resetStore());

const store = createStore(reducerApp);

const rootElement = document.getElementById('react-root');

Meteor.startup(() =>
  hydrate(
    <MuiThemeProvider theme={theme}>
      <CssBaseline />
      <ApolloProvider client={apolloClient}>
        <ApolloHooksProvider client={apolloClient}>
          <Provider store={store}>
            <BrowserRouter>
              <Switch>
                <App />
              </Switch>
            </BrowserRouter>
          </Provider>
        </ApolloHooksProvider>
      </ApolloProvider>
    </MuiThemeProvider>,
    rootElement,
  ),
);
0

There are 0 best solutions below