Project: Emoji Story

ROLE: Full-stack Web Developer

TIME FRAME: March 2022 - Present



Emoji Story is a fun web app that allows users to generate stories with emojis using AI and share them on the platform. The project uses the revolutionary AI, GTP-3 to automatically generate natural language based on Emojis that users input.

I was the full-stack developer for this platform and worked with UX Designers to make this a reality. I used Next.js to build API endpoints, Cloud Firestore for the database, and Firebase for authentication.


  1. User Authentication
  2. Storing user data and permissions
  3. Using GTP-3 from Open AI to generate Stories
  4. Sharing user stories
phone mockup

Teck stack overview

Emoji Story uses Next.js for rendering our server and Firebase for handling our backend infrastructure. Next.js helps us set up our react environment for both client-side and server-side rendering. We used both the client and admin Firebase SDK for user authentication, querying from our NoSQL database, and storing data. Lastly, we also used TypeScript for better development.


The key technology that we use is the GTP-3 AI from Open AI. It allows us to generate natural language based on user input. We used the OpenAI Node.js Library to interact with the AI. To allow the front-end to interact with it, we exposed it to a Next.js end-point that validates the user token first.

It basically works like this:

  1. User inputs string of emojis "🛀🏿🕡"
  2. AI creates a family-friendly story:

"I was taking a relaxing bath when I suddenly remembered that I needed to pick up my kids from school! I jumped out of the tub, grabbed my clothes, and ran out the door. I arrived at the school just in time to see my kids getting on the bus. Phew!”

Database Structure

Our NoSQL Firestore database comprises two collections: the stories collection and the users collection. We do not store a story collection in each user because we wanted to be able to query stories easily for our featured stories functionality. The query speed is still O(1) because of Firestore indexing.

The example below is a story Document from our database. We can see that we store the "uid” as a foreign key to associate with each user. This is used for authorization. The reason we also store the user’s name "createdBy” is so that we do not have to query twice to obtain the name. In NoSQL databases, it is better to duplicate data to obtain better performance.

createdBy: "Matthew Wang"

date: May 3, 2022 at 3:20:38 PM UTC+8

emojis: "🍥👎🏽👎🏽🦄"

text": Once upon a time, there was a magical kingdom where unicorns roamed free. The people of the kingdom were very happy and content. However, one day, two evil witches came to the kingdom and cast a spell that made all of the unicorns disappear. The people were very sad and upset. The witches laughed and said, "There's no such thing as magic! Now you'll never see your precious unicorns again!""

uid": WiGT0mYXeuZIwCvNyFsvqvLlam02"

User Authentication

Currently, we allow for Google Sign up and Facebook Sign up. When the user signs in we use the Firebase SDK for authenticating and retrieving data from each user. This is all coded using the Firebase SDKs. After the user logs in, the JWT refresh token of the user is stored in a cookie. This is so that we can also validate the user on the server-side if needed.

The Client-side authentication is for user interaction with the database such as reads and deletes.

Server-side authentication is used for interacting with the GTP-3 AI, creating stories, deleting user accounts, and redirecting users in case they are not logged in.


Firebase is a very powerful platform for managing back-end-related tasks and is very easy to set up user permissions and integrate with the front-end.

Serverless can be quite slow with user authentication and we might migrate to using AWS EC2 instances.