DEV Community

Nader Dabit
Nader Dabit

Posted on • Edited on

Introducing Conference App in a Box

Deploy a themeable, customizable, full stack and cross-platform mobile app for your next event in minutes.

πŸ›  Built with React Native, GraphQL, AWS Amplify, & AWS AppSync.

This app is open source. View the repo here.

Last Week at Chain React I gave a talk titled "Hooking Up A Conference In Real-Time With GraphQL".

In the presentation I talked about the React Native Amazon Conference that was held in January 2019 and how we took some ideas from their conference app and applied them to the Chain React conference app.

The main feature we wanted to add was real-time chat so that attendees could discuss each talk and even ask the speaker questions that could then later be answered by the speaker.

During the presentation I showed how we took the 2018 version of the Chain React conference app and updated it to use a GraphQL backend that handled comments for each talk. I worked with Robin Heinze from Infinite Red over the course of a couple of days to do this.

I also showed how we handled identity and abuse by adding the ability to report comments and building an admin panel that allows moderators to monitor reported comments, block devices, and delete reported comments.

While building the app, I had the idea to make the functionality re-usable because I know there are so many events and conferences popping up. I thought why not try to create something that everyone could use?

The challenge: The problem with something like this is that building out everything that encompasses the back end (authentication, database, api) is usually not easily reproducible.

The solution: AWS Amplify allows you to deploy entire backends using a base configuration. For example if I have an app that has a combination of authentication, databases, APIs and serverless functions and I wanted to reproduce this back end across multiple apps or share it with others, the only thing I would need to do would be to share the amplify folder and anyone could get up and running with the same back end with just a couple of commands on their terminal.

I decided to build a themeable conference & event app that was easily customizable and could be deployed in this way using Amplify.



Deploying the app

The code for the app is located here. Before deploying the app, I'd also take a look at the next section (How it works) so you know how everything works.

To deploy the app, you can follow these steps:

# 1. Clone the repo & install the dependencies

~ git clone https://github.com/dabit3/conference-app-in-a-box.git

~ cd conference-app-in-a-box

~ npm install

# 2. Initialize and deploy the Amplify project

~ amplify init

? Enter a name for the environment: dev (or whatever you would like to call this env)
? Choose your default editor: <YOUR_EDITOR_OF_CHOICE>
? Do you want to use an AWS profile? Y

~ amplify push

? Are you sure you want to continue? Y
? Do you want to generate code for your newly created GraphQL API? N

# We already have the GraphQL code generated for this project, so generating it here is not necessary.

# 3. Start the app

~ react-native run-ios

# or

~ react-native run-android
Enter fullscreen mode Exit fullscreen mode

Now that the back end has been deployed you can open the app, create an account and sign in.

Populating the database

Next go into the AppSync console to interact with the API by running the following command:

~ amplify console api
Enter fullscreen mode Exit fullscreen mode

From the AppSync console, click on Queries to open the GraphiQL editor. When prompted to "Login with User Pools", you can login with your new username and use the aws_user_pools_web_client_id located in aws-exports.js for the ClientId.

Creating mutations

Create a new talk with the following mutation:

mutation createTalk {
  createTalk(input: {
    name: "Performance In React Native",
    summary: "In this talk, we will look at the various tips and tricks for taking full advantage of React Native and using the performance attributes of the new architecture.",
    speakerName: "Ram Narasimhan",
    speakerBio: "Software Engineer at Facebook",
    time: "9:00 AM - 9:30 AM",
    timeStamp: "1573491600",
    date: "November 10",
    location: "Armory",
    speakerAvatar: "https://pbs.twimg.com/profile_images/875450414161772544/UjefWmmL_400x400.jpg"
  }) {
    id name speakerBio speakerName speakerAvatar location date time timeStamp
  }
}
Enter fullscreen mode Exit fullscreen mode

Querying for data

When you reload the app, it should list this talk when launched.

To query for all talks in the AppSync console, you can run the following query:

query listTalks {
  listTalks {
    items {
      id
      name
      summary
      speakerName
      speakerBio
      time
      timeStamp
      date
      location
      speakerAvatar
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

How it works

The code for the app is located here.

In the project, you'll notice a folder named amplify. This folder contains the back end for the app that can be redeployed in anyone's account. In the amplify folder you'll see a backend folder. In this folder you'll see the configuration for the two main features:

  1. Authentication service (powered by Amazon Cognito)
  2. GraphQL API (built with AWS AppSync)

In the backend/api folder you'll see the GraphQL API configuration as well as the base GraphQL Schema.

This is the base GraphQL Schema. You'll see that the base schema looks like this:

type Talk @model {
  id: ID!
  name: String!
  speakerName: String!
  speakerBio: String!
  time: String
  timeStamp: String
  date: String
  location: String
  summary: String!
  twitter: String
  github: String
  speakerAvatar: String
  comments: [Comment] @connection(name: "TalkComments")
}

type Comment @model {
  id: ID!
  talkId: ID
  talk: Talk @connection(sortField: "createdAt", name: "TalkComments", keyField: "talkId")
  message: String
  createdAt: String
  createdBy: String
  deviceId: ID
}

type Report @model {
    id: ID!
    commentId: ID!
    comment: String!
    talkTitle: String!
    deviceId: ID
}

type ModelCommentConnection {
    items: [Comment]
    nextToken: String
}

type Query {
  listCommentsByTalkId(talkId: ID!): ModelCommentConnection
}
Enter fullscreen mode Exit fullscreen mode

Not that the Report feature is not implemented in the app, but it is there so if you wanted to add a report feature and the admin dashboard you wouldn't have to configure anything else.

If you've never worked with Amplify before you may not be aware of the @model and @connection directives. These are part of the GraphQL Transform library of the Amplify CLI.

@model - Decorate any base type with this directive to get CRUD and list query and mutation definitions, a DynamoDB table, and resolvers created for the GraphQL operations.

@connection - Use this directive to specify relationships between fields (one to many, many to many).

Customizing the GraphQL schema

This schema can be edited. If your event needs additional fields, you can update the backend by doing the following:

  1. Update the schema (located at amplify/backend/api/rnconfinabox/schema.graphql).

  2. Redeploy the back end

~ amplify push
Enter fullscreen mode Exit fullscreen mode

If you or anyone you know needs help getting up and running with an app for your next event using this project, reach out to me on Twitter, I'd be happy to help!

My Name is Nader Dabit. I am a Developer Advocate at Amazon Web Services working with projects like AWS AppSync and AWS Amplify. I specialize in cross-platform & cloud-enabled application development.

Top comments (12)

Collapse
 
getterhiss profile image
Getter Hiss

@dabit3 Nader, just curious if this is expected behavior with the AWS GraphQL endpoint.

listTalks(filter: {name: {contains: β€œGetter”}}, limit: 1)

I get zero results, but nextToken is populated. When I query that, I get my result(s).

Seems like the expected behavior should be to filter, then run limit. It’s running limit on the records, then filtering.

Collapse
 
dabit3 profile image
Nader Dabit

So I think the issue here is that, by default, this query will perform a scan operation and then a filter on the scanned items. By default, I think the number that it returns is 10, so if your item is not contained in the first 10 items it will return zero and a next token.

You could instead update the operation to be a query vs a scan (by using the @key directive), or you could increase the limit.

This is more of a quirk / implementation detail of DynamoDB than anything else.

The scan operation will scan every item in a db (or the first n items if we set a limit, in our case 1) and then perform a filter on those results. By contrast, a query will only query on a set key, so in general for larger data sets a query is the way to go.

aws-amplify.github.io/docs/cli-too...

Collapse
 
getterhiss profile image
Getter Hiss

Yeah, it seems like a DynamoDB quirk. I only had about 4 records and limit: 1 to test filtering.

I never jumped on the NoSQL bandwagon. Give me SQL anyday. I find most data, for 99% of applications out there, is relational. Not to mention most won't run up against scaling issues with just using Postgres.

Have you thought about doing this same Amplify GraphQL example with Amazon Aurora Serverless? I think it'd be great to compare them side-by-side.

Thread Thread
 
dabit3 profile image
Nader Dabit

One of my favorite videos that shows what NoSQL can do is this one: youtube.com/watch?v=HaEPXoXVf2k , it also goes into theory around by NoSQL has become so popular. We're definitely working on more support as well for relational databases, you'll see more from us later this year.

Collapse
 
younesh1989 profile image
Younes Henni

Spot on Nader.

Collapse
 
markpieszak profile image
Mark Pieszak

πŸ₯‡πŸ₯‡πŸ₯‡

Collapse
 
efleurine profile image
Emmanuel

I might need something similar for our dev conference in Haiti πŸ‡­πŸ‡Ή this November. That will be a very good start

Collapse
 
dabit3 profile image
Nader Dabit

Awesome, let me know if I can help you in any way!

Collapse
 
anthonybrown profile image
Tony Brown

Nice work @Nader. β€οΈπŸ’£πŸ€―πŸ”₯πŸ’₯

Collapse
 
slopeofhope81 profile image
Steve Lim

Just out of curiosity, if I don't use expo, does Amplify have a way/tool to release the react-native bundle to the app store?

Collapse
 
dabit3 profile image
Nader Dabit

Hi Steve. No, Amplify does not offer this directly, but you should be able to bundle to .ipa or .apk directly from either Xcode (iOS) or from the command line (Android)

Collapse
 
leland_smith_08eaf1e45d59 profile image
Leland SMITH

This is an awesome App. Thanks Nadder. I am having one strange problem.
has anyone had problems displaying images? I can not get the logo or speaker Avatar to display.