我正在开发一个聊天应用程序,但遇到 graphql 订阅返回 null 的问题。我查看了其他类似/相同的主题,但不幸的是它没有帮助我。 查询和变异工作正常。
谁能告诉我我做错了什么?
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