graphQL 订阅返回 null

时间:2021-05-02 22:50:34

标签: javascript react-native graphql apollo publish-subscribe

我正在开发一个聊天应用程序,但遇到 graphql 订阅返回 null 的问题。我查看了其他类似/相同的主题,但不幸的是它没有帮助我。 查询和变异工作正常。

谁能告诉我我做错了什么?

GraphQL playground

Server.ts:

const { GraphQLServer, PubSub } = require("graphql-yoga");

const chat = [
  {
    id: 0,
    name: "Beer group",
    messages: [
      {
        user: {
          name: "PJ",
          profilePic: "PJ pic",
        },
        body: "Hey mates! Beer tonight?",
      },
    ],
  },
  {
    id: 1,
    name: "Bikes group",
    messages: [
      {
        user: {
          name: "MJ",
          profilePic: "MJ pic",
        },
        body: "Ride tomorrow morning?",
      },
    ],
  },
];

const typeDefs = `

type Query {
  rooms: [RoomsType]
  messages(roomID: String!): [SingleMessageType]
}

type Mutation {
postMessage(user: String!, body: String!, roomID: String!): ID!
createRoom(name: String!): ID!
}

type Subscription {
  messageAdded(roomID: String!): [SingleMessageType]
}

type RoomsType {
  id: String
  name: String
}

type SingleMessageType {
  user: SingleUserType
  body: String
}

type SingleUserType {
  name: String
  profilePic: String
}
`;

const subscribers = [];
const onRoomsUpdates = (fn) => subscribers.push(fn);

const resolvers = {
  Query: {
    rooms: () => chat,
    messages: (parent, { roomID }) => chat[roomID].messages,
  },
  Mutation: {
    postMessage: (parent, { user, body, roomID }) => {
      // const id = rooms[roomID].messages.length;
      chat[roomID].messages.push({
        user: {
          name: user,
          profilePic: "USER pic",
        },
        body: body,
      });
      subscribers.forEach((fn) => fn());
      return roomID;
    },
    createRoom: (parent, { name }) => {
      const id = rooms.length;
      const messages = [];
      chat.push({ id, name, messages });
      return id;
    },
  },
  Subscription: {
    messageAdded: {
      subscribe: (parent, args, { pubsub, name, body }) => {
        const channel = Math.random().toString(36).slice(2, 15);
        onRoomsUpdates(() =>
          pubsub.publish(channel, {
            messages: [{ user: { name: name, profilePic: "" }, body: body }],
          })
        );
        setTimeout(
          () =>
            pubsub.publish(channel, {
              messages: [{ user: { name: name, profilePic: "" }, body: body }],
            }),
          0
        );
        return pubsub.asyncIterator(channel);
      },
    },
  },
};

const pubsub = new PubSub();
const server = new GraphQLServer({ typeDefs, resolvers, context: { pubsub } });
server.start(({ port }) => {
  console.log(`Server on http://localhost:${port}/`);
});

查询.ts:

import { gql } from "@apollo/client";

const GET_ROOMS = gql`
  query GetRooms {
    rooms {
      id
      name
    }
  }
`;

const GET_MESSAGES = gql`
  query GetMessages($roomID: String!) {
    messages(roomID: $roomID) {
      user {
        name
        profilePic
      }
      body
    }
  }
`;

const POST_MESSAGE = gql`
  mutation postMessage($user: String!, $roomID: String!, $body: String!) {
    postMessage(user: $user, roomID: $roomID, body: $body)
  }
`;

const MESSAGE_SUBSCRIPTION = gql`
  subscription messageAdded($roomID: String!) {
    messageAdded(roomID: $roomID) {
      user {
        name
        profilePic
      }
      body
    }
  }
`;

export { GET_ROOMS, GET_MESSAGES, POST_MESSAGE, MESSAGE_SUBSCRIPTION };

RoomScreen.tsx:

import React from "react";
import { Text, View } from "react-native";
import "react-native-gesture-handler";
import {
  GET_MESSAGES,
  MESSAGE_SUBSCRIPTION,
  POST_MESSAGE,
  // GET_ROOMS,
} from "./Querries";
import { useQuery, useMutation } from "@apollo/client";
// import PostMessage from "./PostMessage";
import { GiftedChat } from "react-native-gifted-chat";
import { styles } from "./styles";
// import { login } from "../misc/crede";

export default function RoomScreen(props) {
  const roomID = props.route.params.roomID;
  const [postMessage] = useMutation(POST_MESSAGE);
  const { data, loading, error, subscribeToMore } = useQuery(GET_MESSAGES, {
    variables: { roomID: roomID },
  });

  if (loading) return <Text>Loading...</Text>;
  if (error) return <Text>Error :(</Text>;

  subscribeToMore({
    document: MESSAGE_SUBSCRIPTION,
    variables: { roomID: roomID },
    updateQuery: (prev, { subscriptionData }) => {
      if (!subscriptionData.data) return prev;
      const newFeedItem = subscriptionData.data;
      return Object.assign({}, prev, {
        chat: {
          ...prev.chat,
          messages: [...prev.messages, newFeedItem],
        },
      });
    },
  });

  return (
    <View style={styles.container}>
      <GiftedChat
        messages={data.messages.map((msg) => ({
          // _id: msg.id,
          text: msg.body,
          user: {
            _id: msg.user.name,
            name: msg.user.name,
            avatar: msg.user.profilePic,
          },
        }))}
        onSend={(e) => {
          postMessage({
            variables: {
              body: e[0].text,
              roomID: roomID,
              user: "User",
              // password: login.password,
            },
          });
        }}
        user={{ _id: "User" }}
        inverted={false}
        showUserAvatar={false}
        renderUsernameOnMessage={true}
      />
    </View>
  );
}

完整代码在此链接下:https://github.com/PatrykJamroz/chat-app/tree/local-graphql-remove-phoenix-2

0 个答案:

没有答案