Add chat to your app

chat

1. Define a new model for your messages

Start by defining a new model for your messages. Open the file amplify/backend/api/graphqlrealtimerace/schema.graphql and add the following definitions.

type Message
  @model
  @key(
    fields: ["eventId", "createdAt"]
    name: "ByEventId"
    queryField: "messagesByEventId"
  )
  @auth(
    rules: [
      { allow: owner }
      { allow: private, operations: [read] }
    ]
  ) {
  id: ID!
  owner: ID
  content: String!
  event: Event @connection(fields: ["eventId"])
  eventId: ID
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
}

type Subscription {
  onMutateMessage(eventId: ID): Message
    @aws_subscribe(mutations: ["createMessage", "updateMessage"])
}

This Message model allows signed-in users to create messages and allows all signed-in users to read all messages. A message is associated with an Event. An event will act as a “chatroom”. Users are able to select an event and start chatting about the event as things are happening at the race. We’re also defining an additional subscription onMutateMessage that is triggered any time an event is created and updated. The eventId argument tells AppSync how to filter the subscription before sending it to the user. In this case, a user can subscribe to receive real time, in-line notifications for messages that belong to as specific event.

Deploy your changes from the cli:

amplify push --yes

2. Update your code

You need a few more packages to support the chat application. Install them with

yarn add react-hook-form uuid
yarn add -D @types/uuid

Update the file src/pages/Chat.tsx:

[ 🌟 ] src/pages/Chat.tsx

This code uses the Amplify API library to send and receive messages.

  1. It fetches the list of existings events

    API.graphql({ query: Queries.listEvents })
    
  2. When a user selects an event,

    1. it fetches all the messages for that event
    API.graphql({
       query: Queries.messagesByEventId,
       variables: {
         eventId: selected.id,
         sortDirection: 'DESC',
         limit: 20,
       },
     })
    
    1. and establishes a subscripton to receive messages from other users in the chat
    API.graphql({
          query: onMutateMessage,
          variables: { eventId: selected.id },
        }).subscribe({
        next: (resp) => {
          const msg: Msg = resp.value.data.onMutateMessage!
          if (pane.current) {
          setMessages((msgs) => uniqBy(sortBy([...msgs, msg], 'createdAt'), 'id'))
        },
      })
    
  3. It uses a mutation to send a message

    API.graphql({ query: createMessage, variables: { input: msg } })
    

3. Try out the chat

Reload your application if needed and head to the chat page. You should be able to select an event and create/receive messages. You can create a few more users in the Admin UI to verify that you are receiving messages from all users in the chat.

chat