• Stars
    star
    236
  • Rank 170,480 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

React Native Enterprise Social Messaging App

Heard - An enterprise React Native Social Messaging App

Built with AWS AppSync & AWS Amplify

Todo

  • Add subscriptions for real time updates / messages in feed
  • Add user profile section
  • Add "follower" tab

Getting Started

Cloning the project & creating the services

  1. Clone the project
git clone 
  1. Install dependencies
yarn
# or
npm install
  1. Create new AWS Mobile Project
awsmobile init
  1. Add Authentication service
awsmobile user-signin enable
  1. Push configuration to AWS Mobile Hub
awsmobile push

Configuring the AWS AppSync API

  1. Create & configure a new AppSync API
  • Visit the AWS AppSync console and create a new API.
  • In Settings, set the Auth mode to Amazon Cognito User Pool and choose the user pool created in the initial service creation.
  1. In index.js on line 11, change <YOURAPPSYNCENDPOINT> to the endpoint given to you when you created the AppSync API.

  2. Attach the following Schema:

input CreateFollowingInput {
	id: ID
	followerId: ID!
	followingId: ID!
}

input CreateMessageInput {
	messageId: ID
	authorId: ID!
	createdAt: String
	messageInfo: MessageInfoInput!
	author: UserInput
}

input CreateUserInput {
	userId: ID!
	username: String!
}

input DeleteFollowingInput {
	id: ID!
}

input DeleteMessageInput {
	authorId: ID!
	createdAt: String!
}

input DeleteUserInput {
	userId: ID!
}

type Following {
	id: ID
	followerId: ID!
	followingId: ID!
}

type FollowingConnection {
	items: [Following]
	nextToken: String
}

type ListUserConnection {
	items: [User]
	nextToken: String
}

type Mutation {
	createMessage(input: CreateMessageInput!): Message
	updateMessage(input: UpdateMessageInput!): Message
	deleteMessage(input: DeleteMessageInput!): Message
	createUser(input: CreateUserInput!): User
	updateUser(input: UpdateUserInput!): User
	deleteUser(input: DeleteUserInput!): User
	createFollowing(input: CreateFollowingInput!): Following
	updateFollowing(input: UpdateFollowingInput!): Following
	deleteFollowing(input: DeleteFollowingInput!): Following
}

type Query {
	getMessage(authorId: ID!, createdAt: String!): Message
	listMessages(first: Int, after: String): MessageConnection
	listFollowing: [Following]
	getUser(userId: ID!): User
	listUsers(first: Int, after: String): ListUserConnection
	queryMessagesByAuthorIdIndex(authorId: ID!, first: Int, after: String): MessageConnection
}

type Subscription {
	onCreateMessage(messageId: ID, authorId: ID, createdAt: String): Message
		@aws_subscribe(mutations: ["createMessage"])
	onUpdateMessage(messageId: ID, authorId: ID, createdAt: String): Message
		@aws_subscribe(mutations: ["updateMessage"])
	onDeleteMessage(messageId: ID, authorId: ID, createdAt: String): Message
		@aws_subscribe(mutations: ["deleteMessage"])
	onCreateUser(userId: ID, username: String): User
		@aws_subscribe(mutations: ["createUser"])
	onUpdateUser(userId: ID, username: String): User
		@aws_subscribe(mutations: ["updateUser"])
	onDeleteUser(userId: ID, username: String): User
		@aws_subscribe(mutations: ["deleteUser"])
	onCreateFollowing(id: ID, followerId: ID, followingId: ID): Following
		@aws_subscribe(mutations: ["createFollowing"])
	onUpdateFollowing(id: ID, followerId: ID, followingId: ID): Following
		@aws_subscribe(mutations: ["updateFollowing"])
	onDeleteFollowing(id: ID, followerId: ID, followingId: ID): Following
		@aws_subscribe(mutations: ["deleteFollowing"])
}

type Message {
	messageId: ID!
	authorId: ID!
	messageInfo: MessageInfo!
	author: User
	createdAt: String
}

type MessageConnection {
	items: [Message]
	nextToken: String
}

type MessageInfo {
	text: String!
}

input MessageInfoInput {
	text: String!
}

input UpdateFollowingInput {
	id: ID!
	followerId: ID
	followingId: ID
}

input UpdateMessageInput {
	messageId: ID
	authorId: ID!
	createdAt: String!
}

input UpdateUserInput {
	userId: ID!
	username: String
}

type User {
	userId: ID!
	username: String
	messages(limit: Int, nextToken: String): MessageConnection
	following(limit: Int, nextToken: String): UserFollowingConnection
	followers(limit: Int, nextToken: String): UserFollowersConnection
}

type UserConnection {
	items: [User]
	nextToken: String
}

type UserFollowersConnection {
	items: [User]
	nextToken: String
}

type UserFollowingConnection {
	items: [User]
	nextToken: String
}

input UserInput {
	userId: ID!
	username: String!
}
  1. Create the following DynamoDB Tables
  • HeardMessageTable
  • HeardFollowingTable
  • HeardUserTable
  1. Add the following indexes:
  • In HeardMessageTable, create an authorId-index with the authorId as the primary / partition key.
  • In HeardFollowingTable, create a followingId-index with the followingId as the primary / partition key.
  • In HeardFollowingTable, create a followerId-index with the followerId as the primary / partition key.

To create an index, click on the table you would like to create an index on, click on the indexes tab, then click Create Index .

  1. Create the following resolvers:

Message author: User: HeardUserTable

// request mapping template
{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "userId": $util.dynamodb.toDynamoDBJson($ctx.source.authorId),
    }
}

// response mapping template
$util.toJson($ctx.result)

ListUserConnection items: [User]: HeardUserTable

// request mapping template
{
    "version" : "2017-02-28",
    "operation" : "Scan",
}

// response mapping template
$util.toJson($ctx.result.items)

Query getUser(...): User: HeardUserTable

// request mapping template
{
  "version": "2017-02-28",
  "operation": "GetItem",
  "key": {
    "userId": $util.dynamodb.toDynamoDBJson($ctx.args.userId),
  },
}

// response mapping template
$util.toJson($context.result)

Query listUsers(...): ListUserConnection: HeardUserTable

// request mapping template
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": $util.defaultIfNull(${ctx.args.limit}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.nextToken, null))
}

// response mapping template
$util.toJson($ctx.result.items)

Query listFollowing: [Following]: HeardFollowingTable

// request mapping template
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "followerId-index",
    "query" : {
        "expression": "followerId = :id",
        "expressionValues" : {
            ":id" : {
                "S" : "${ctx.identity.sub}"
            }
        }
    }
}

// response mapping template
$util.toJson($ctx.result.items)

Query queryMessagesByAuthorIdIndex(...): MessageConnection: HeardMessageTable

// request mapping template
{
  "version": "2017-02-28",
  "operation": "Query",
  "query": {
    "expression": "#authorId = :authorId",
    "expressionNames": {
      "#authorId": "authorId",
    },
    "expressionValues": {
      ":authorId": $util.dynamodb.toDynamoDBJson($ctx.args.authorId),
    },
  },
  "index": "authorId-index",
  "limit": $util.defaultIfNull($ctx.args.first, 20),
  "nextToken": $util.toJson($util.defaultIfNullOrEmpty($ctx.args.after, null)),
  "scanIndexForward": true,
  "select": "ALL_ATTRIBUTES",
}

// response mapping template
$util.toJson($context.result)

Mutation createFollowing(...): Following: HeardFollowingTable

// request mapping template
{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
     ## If object "id" should come from GraphQL arguments, change to $util.dynamodb.toDynamoDBJson($ctx.args.id)
    "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(#id)",
    "expressionNames": {
      "#id": "id",
    },
  },
}

// response mapping template
$util.toJson($context.result)

Mutation deleteFollowing(...): Following: HeardFollowingTable

// request mapping template
{
  "version": "2017-02-28",
  "operation": "DeleteItem",
  "key": {
    "id": $util.dynamodb.toDynamoDBJson($ctx.args.input.id),
  },
}

// response mapping template
$util.toJson($context.result)

Mutation createUser(...): User: HeardUserTable

// request mapping template
{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "userId": $util.dynamodb.toDynamoDBJson($ctx.args.input.userId),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(#userId)",
    "expressionNames": {
      "#userId": "userId",
    },
  },
}

// response mapping template
$util.toJson($context.result)

Mutation createMessage(...): Message: HeardMessageTable

// request mapping template
#set($time = $util.time.nowISO8601())

#set($attribs = $util.dynamodb.toMapValues($ctx.args.input))
#set($attribs.createdAt = $util.dynamodb.toDynamoDB($time))
#set($attribs.messageId = $util.dynamodb.toDynamoDB($util.autoId()))

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "authorId": $util.dynamodb.toDynamoDBJson($ctx.args.input.authorId),
    "createdAt": $util.dynamodb.toDynamoDBJson($time),
  },
  "attributeValues": $util.toJson($attribs),
  "condition": {
    "expression": "attribute_not_exists(#authorId) AND attribute_not_exists(#createdAt)",
    "expressionNames": {
      "#authorId": "authorId",
      "#createdAt": "createdAt",
    },
  },
}

// response mapping template
$util.toJson($context.result)

User messages(...): MessageConnection: HeardMessageTable

// request mapping template
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "authorId-index",
    "query" : {
        "expression": "authorId = :id",
        "expressionValues" : {
            ":id" : {
                "S" : "${ctx.source.userId}"
            }
        }
    },
    "limit": $util.defaultIfNull(${ctx.args.first}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
}

// response mapping template
$util.toJson($ctx.result)

User following(...): UserFollowingConnection: HeardFollowingTable

// request mapping template
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "followerId-index",
    "query" : {
        "expression": "followerId = :id",
        "expressionValues" : {
            ":id" : {
                "S" : "${ctx.source.userId}"
            }
        }
    }
    ## ,
    ## "limit": $util.defaultIfNull(${ctx.args.first}, 20),
    ## "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
}

// response mapping template
## Pass back the result from DynamoDB. **
## $util.qr($util.error($ctx.result))
$util.toJson($ctx.result)

UserFollowingConnection items: [User]: HeardUserTable

// request mapping template
## UserFollowingConnection.items.request.vtl **
 
#set($ids = [])
#foreach($following in ${ctx.source.items})
    #set($map = {})
    $util.qr($map.put("userId", $util.dynamodb.toString($following.get("followerId"))))
    $util.qr($ids.add($map))
#end
 
{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "HeardUserTable": {
           "keys": $util.toJson($ids),
           "consistentRead": true
       }
    }
}

// response mapping template
## Pass back the result from DynamoDB. **
#if( ! ${ctx.result.data} )
  $util.toJson([])
#else
  $util.toJson($ctx.result.data.HeardUserTable)
#end

## $util.toJson($ctx.result.data.HeardUserTable)

More Repositories

1

awesome-aws-amplify

Curated list of AWS Amplify Resources
1,782
star
2

polygon-ethereum-nextjs-marketplace

A full stack digital marketplace running on Ethereum with Polygon & Next.js
JavaScript
1,303
star
3

full-stack-ethereum

Building full stack apps with Solidity, Ethers.js, Hardhat, and The Graph
TypeScript
802
star
4

react-native-ai

Full stack framework for building cross-platform mobile AI apps
TypeScript
794
star
5

semantic-search-nextjs-pinecone-langchain-chatgpt

Embeds text files into vectors, stores them on Pinecone, and enables semantic search using GPT3 and Langchain in a Next.js UI
TypeScript
739
star
6

awesome-aws-appsync

Curated list of AWS AppSync Resources
625
star
7

gpt-travel-advisor

reference architecture for building a travel application with GPT3
TypeScript
543
star
8

foundry-cheatsheet

522
star
9

complete-guide-to-full-stack-solana-development

Code examples for the blog post titled The Complete Guide to Full Stack Solana Development with React, Anchor, Rust, and Phantom
JavaScript
474
star
10

dynamodb-documentclient-cheat-sheet

DynamoDB JavaScript DocumentClient cheat sheet
443
star
11

full-stack-web3

A full stack web3 on-chain blog and CMS
JavaScript
420
star
12

next.js-amplify-workshop

AWS Amplify Next.js workshop
JavaScript
360
star
13

gatsby-auth-starter-aws-amplify

Starter Project with Authentication with Gatsby & AWS Amplify
JavaScript
320
star
14

gpt-fine-tuning-with-nodejs

GPT Fine-Tuning using Node.js - an easy to use starter project
JavaScript
250
star
15

full-stack-serverless-code

Code examples for my book Full Stack Serverless with O'Reilly Publications
JavaScript
244
star
16

openai-functions-god-app

TypeScript
240
star
17

aws-appsync-react-workshop

Building real-time offline-ready Applications with React, GraphQL & AWS AppSync
JavaScript
228
star
18

nextjs-chatgpt-plugin-starter

ChatGPT plugin starter project using Next.js
TypeScript
209
star
19

micro-frontend-example

Building Micro Frontends with React, Vue, and Single-spa
JavaScript
207
star
20

amplify-photo-sharing-workshop

Building full-stack cloud apps with AWS Amplify and React
JavaScript
197
star
21

chicken-tikka-masala-recipe

Nader's chicken tikka masala recipe
PHP
193
star
22

decentralized-identity-example

An authentication system built with Ceramic & self.id
JavaScript
190
star
23

aws-amplify-workshop-react

Building Serverless React Applications with AWS Amplify
172
star
24

building-a-subgraph-workshop

In this workshop you'll learn how to build an NFT Subgraph using any smart contract or smart contracts.
TypeScript
165
star
25

graphql-recipes

A list of GraphQL recipes that, when used with the Amplify CLI, will deploy an entire AWS AppSync GraphQL backend.
158
star
26

next.js-cdk-amplify-workshop

Full stack serverless workshop with Next.js, CDK, and AWS Amplify
JavaScript
157
star
27

supabase-next.js

Full stack app built with Supabase and Next.js
JavaScript
152
star
28

titter

Decentralized Twitter prototype built with Polygon, GraphQL, Next.js, Ceramic, Arweave, and Bundlr
JavaScript
152
star
29

supabase-nextjs-auth

Example project implementing authentication, authorization, and routing with Next.js and Supabase
JavaScript
151
star
30

react-native-in-action

React Native in Action, written for Manning Publications
146
star
31

prompt-engineering-for-javascript-developers

Notes summarized from ChatGPT Prompt Engineering for Developers by DeepLearning.ai
145
star
32

write-with-me

Real-time Collaborative Markdown Editor
JavaScript
144
star
33

foundry-workshop

Building and testing smart contracts with Foundry
Solidity
144
star
34

aws-amplify-workshop-react-native

Building Cloud-enabled Mobile Applications with React Native & AWS Amplify
JavaScript
139
star
35

lens-protocol-frontend

Example of a basic front end built on Lens Protocol
JavaScript
136
star
36

cdk-graphql-backend

A real-time GraphQL API deployed with CDK using AWS AppSync, AWS Lambda, and DynamoDB
TypeScript
131
star
37

create-new-cli

Create your own CLI using a series of simple commands.
JavaScript
128
star
38

perma

Perma is a web3 prototype of permanent video storage and viewing using Next.js, Arweave, and Bundlr.
JavaScript
120
star
39

appsync-graphql-real-time-canvas

Collaborative real-time canvas built with GraphQL, AWS AppSync, & React Canvas Draw
JavaScript
119
star
40

full-stack-ethereum-marketplace-workshop

Build a Full Stack Marketplace on Ethereum with React, Solidity, Hardhat, and Ethers.js
JavaScript
118
star
41

amplify-auth-demo

Demo of OAuth + Username / Password authentication in AWS Amplify
JavaScript
111
star
42

hype-beats

Real-time Collaborative Beatbox with React & GraphQL
JavaScript
111
star
43

next.js-authentication-aws

This project deploys a Next.js project to AWS with comprehensive authentication enabled
JavaScript
104
star
44

this-or-that

This or that - Real-time atomic voting app built with AWS Amplify
CSS
98
star
45

react-native-deep-linking

Deep Linking set up in a React Native App
Objective-C
96
star
46

beginning-webpack

This repository goes along with the medium post titled "Beginner's guide to Webpack"
JavaScript
95
star
47

react-native-bootcamp

React Native Bootcamp Materials for TylerMcginnis.com
94
star
48

react-native-mobx-list-app

React Native + Mobx List Application
JavaScript
91
star
49

appsync-auth-and-unauth

How to allow both authenticated & unauthenticated access to an API
JavaScript
91
star
50

aws-amplify-workshop-web

Building web applications with React & AWS Amplify
JavaScript
90
star
51

full-stack-ethereum-workshop

Building full stack dapps on the EVM with Hardhat, React, and Ethers.js
HTML
89
star
52

sign-in-with-ethereum-authentication-flow

Example implementation of how to implement Sign In with Ethereum
JavaScript
85
star
53

react-notes

React notes tutorial
JavaScript
84
star
54

vue-graphql-appsync

Vue example using GraphQL with AWS AppSync
JavaScript
81
star
55

lens-pwa

Lens PWA
TypeScript
80
star
56

amplify-datastore-example

Example of basic app using Amplify DataStore
JavaScript
78
star
57

custom-nft-subgraph-workshop

78
star
58

lens-shadcn

Example application combining Lens Protocol, WalletConnect, Next.js, and ShadCN
TypeScript
78
star
59

amplify-with-cdk

An example project showing how to mix CDK with AWS Amplify
TypeScript
77
star
60

react-aws-live-streaming

This project shows how to implement a live-streaming platform using AWS and React
JavaScript
73
star
61

react-native-navigation-v2

Up and running with React Native Navigation - V2 - by Wix
JavaScript
73
star
62

bored-ape-yacht-club-api-and-subgraph

Graph Protocol Subgraph / API for querying Bored Ape Yacht Club NFT data with full text search
TypeScript
70
star
63

react-appsync-graphql-recipe-app

Example application using React + AWS AppSync + GraphQL
JavaScript
70
star
64

react-amplify-appsync-files-s3

An example project showing how to upload and download public and private images in GraphQL using AppSync and S3
JavaScript
70
star
65

react-strict-dom-example

JavaScript
69
star
66

full-stack-react-native-appsync-workshop

Building Full Stack GraphQL Applications with React Native & AWS AppSync
JavaScript
67
star
67

speakerchat

SpeakerChat - Real-time Event Q&A Platform with Markdown Support
JavaScript
66
star
68

react-p2p-messaging

A real-time peer-to-peer messaging app built with React & Gun.js
JavaScript
65
star
69

graphql-suspense

Lightweight component that allows you to interact with a GraphQL API using React Suspense
JavaScript
65
star
70

nuxt-supabase-full-multi-user-blog

Build a mult-user blogging app with Supabase and Nuxt.js
Vue
65
star
71

archive-forever

HTML
63
star
72

next.js-tailwind-authentication

A Next.js authentication starter built with Tailwind and AWS Amplify
JavaScript
63
star
73

near-subgraph-workshop

Building a NEAR NFT API with The Graph
60
star
74

react-authentication-in-depth

Example of User Authentication using React with React Router and AWS Amplify
JavaScript
60
star
75

graphql-api-cdk-serverless-postgres

TypeScript
59
star
76

curious-cases-of-graphql

Code and examples from my talk - Curious Cases of GraphQL
57
star
77

gasless-transactions-example

Example of Gasless Transactions with Biconomy
JavaScript
57
star
78

react-chatbots

Building Chatbots with React, Amazon Lex, AWS Lambda, & AWS Amplify
JavaScript
57
star
79

xmtp-chat-app-nextjs

Real-time encrypted chat, built with XMTP and Next.js
TypeScript
57
star
80

react-native-lens-example

Example app built with React Native Lens UI Kit
JavaScript
55
star
81

lens-protocol-workshop

Introduction to web3 social media with Next.js and Lens Protocol
TypeScript
54
star
82

zora-nextjs-app

Example Full Stack App built with Next.js, Zora, Tailwind, and The Graph
TypeScript
54
star
83

draw-together

TypeScript
53
star
84

terminal-portfolio

TypeScript
51
star
85

arweave-workshop

JavaScript
50
star
86

lens-gated-publications

Example application implementing gated Lens posts, encryption, and decryption
JavaScript
49
star
87

graphql-search

Implementing Search in GraphQL using AWS AppSync & React Apollo
JavaScript
49
star
88

basic-amplify-storage-example

A basic example app showing how to add storage with Amazon S3
JavaScript
49
star
89

production-ready-vue-authentication

How to implement a real user authentication flow in Vue with Vue Router & AWS Amplify.
Vue
48
star
90

build-an-authenticated-api-with-cdk

Workshop - Build an authenticated CDK back end
TypeScript
48
star
91

real-time-image-tracking

Real-time image tracking with React, GraphQL, and AWS AppSync
JavaScript
48
star
92

appsync-lambda-ai

Demo of using a GraphQL resolver to hit a lambda function, then hit a few AI services, and return the response.
JavaScript
47
star
93

appsync-react-native-with-user-authorization

End to end React Native + AWS AppSync GraphQL application with queries, mutations, subscriptions, & user authentication & authorization
JavaScript
47
star
94

openzeppelin-nft-api

Building NFT APIs with OpenZeppelin and The Graph
46
star
95

cryptocoven-api

Cryptocoven Graph API
TypeScript
46
star
96

transilator

Text translation and synthesization Chrome plugin
JavaScript
46
star
97

xp-mobile-account-abstraction

TypeScript
45
star
98

react-native-navigator-experimental-redux

React Native Navigator Experimental with Redux
JavaScript
45
star
99

next.js-amplify-datastore

An example app using Amplify DataStore with Next.js for static site generation, pre-rendering, and SSR
JavaScript
45
star
100

full-stack-warp-arweave

JavaScript
44
star