2

I am using Apollo Server and I want to publish 2 events in the row from same resolver. Both subscriptions are working fine but only if I dispatch only one event. If I try to dispatch both, second subscription resolver never gets called. If I comment out the first event dispatch second works normally.

const publishMessageNotification = async (message, me, action) => {
  const notification = await models.Notification.create({
    ownerId: message.userId,
    messageId: message.id,
    userId: me.id,
    action,
  });

 // if I comment out this one, second pubsub.publish starts firing
  pubsub.publish(EVENTS.NOTIFICATION.CREATED, {
    notificationCreated: { notification },
  });

  const unseenNotificationsCount = await models.Notification.find({
    ownerId: notification.ownerId,
    isSeen: false,
  }).countDocuments();

  console.log('unseenNotificationsCount', unseenNotificationsCount);// logs correct value

  // this one is not working if first one is present
  pubsub.publish(EVENTS.NOTIFICATION.NOT_SEEN_UPDATED, {
    notSeenUpdated: unseenNotificationsCount,
  });
};

I am using default pubsub implementation. There are no errors in the console.

import { PubSub } from 'apollo-server';

import * as MESSAGE_EVENTS from './message';
import * as NOTIFICATION_EVENTS from './notification';

export const EVENTS = {
  MESSAGE: MESSAGE_EVENTS,
  NOTIFICATION: NOTIFICATION_EVENTS,
};

export default new PubSub();
marko kraljevic
  • 343
  • 5
  • 15

2 Answers2

0

Make sure, that you use pubsub from context of apollo server, for example:

Server:

const server = new ApolloServer({
  schema: schemaWithMiddleware,
  subscriptions: {
    path: PATH,
    ...subscriptionOptions,
  },
  context: http => ({
    http,
    pubsub,
    redisCache,
  }),
  engine: {
    apiKey: ENGINE_API_KEY,
    schemaTag: process.env.NODE_ENV,
  },
  playground: process.env.NODE_ENV === 'DEV',
  tracing: process.env.NODE_ENV === 'DEV',
  debug: process.env.NODE_ENV === 'DEV',
});

and example use in resolver, by context:

...
const Mutation = {
  async createOrder(parent, { input }, context) {
    ...
    try {
       ...
        context.pubsub.publish(CHANNEL_NAME, {
          newMessage: {
            messageCount: 0,
          },
          participants,
        });
        dialog.lastMessage = `{ "orderID": ${parentID}, "text": "created" }`;
        context.pubsub.publish(NOTIFICATION_CHANNEL_NAME, {
          notification: { messageCount: 0, dialogID: dialog.id },
          participants,
        });
        ...
      }
      return result;
    } catch (err) {
      log.error(err);
      return sendError(err);
    }
  },
};
...
Oleg
  • 11
  • 2
0

It has been a while since this moment. I have also been a struggle with pubsub not working problem. and I would like to see your ApolloClient setup code. I changed my configurations with regard to graphql version and client-side setup.

  1. graphql version : 14.xx.xx -> 15.3.0

    const client = new ApolloClient({
        uri: 'http://localhost:8001/graphql',
        cache: cache,
        credentials: 'include',
        link: ApolloLink.from([wsLink, httpLink])
    });

I want you to clarify link order, especially about httpLink, if you use in your case, "HttpLink is a terminating Link.", according to Apollo official site. At first, I used link order [httpLink, wsLink]. Therefore, pubsub.publish didn't work.

I hope this answer will help some of graphql users.