Skip to content

Projects

Doan Ngoc Gioi
← All projects

English Dictation Practice App

A dictation web app I built for an English language school: learners listen to short sentences, type them word by word and get instant feedback with a translation, while teachers manage lessons, audio and results in an admin area.

About the project

Learners pick a mission (a short lesson at a given level), play each sentence at normal or slow speed and type what they hear, one box per word. Each answer is checked word by word, wrong words are marked so they can be fixed, and a correct sentence shows its accuracy and translation. A learner can reveal single words as hints, and the end of a mission sums up perfect sentences, accuracy and hints used.

Teachers work in an admin area: they write missions and their sentences (one at a time or in bulk), upload audio or generate it with text-to-speech, choose whether a mission is public or needs a sign-in, publish or hide it, manage users and roles, and review every learner's results.

I built it in phases from a project plan, from authentication and the data model through practice, admin and security rules to deployment on Google Cloud Run.

The screenshots show the app running locally on the Firebase emulators with demo lessons and learners.

Features

  • Missions by level (beginner, intermediate, advanced), public or for signed-in learners only, each with its own short link.
  • Word-by-word practice: one box per word, Enter to check, wrong words marked until fixed, then accuracy and translation.
  • Playback at normal or slow speed, and hints that reveal one word at a time.
  • Results at the end of a mission, saved for signed-in learners.
  • Admin: mission editor with bulk sentence entry, audio upload or text-to-speech, publish and hide, user roles, and a log of every attempt with a per-sentence report.

Screenshots

Practice: a checked sentence with its accuracy and translation
Home: how it works, then the published missions with level and length; some need a sign-in
One box per word: correct words glow green, a wrong word is marked so the learner can fix it before moving on
End of a mission: perfect sentences, accuracy and hints used
Practice on a phone, with slow and normal playback
Admin: the missions library with draft and published missions
Admin: editing a mission's details and its sentences, with bulk add and audio
Admin: learners' results with score, accuracy and a report per attempt

Architecture

  • Next.js (Pages Router) talking directly to Firebase: Authentication for accounts, Firestore for missions, sentences, users and attempts, Storage for audio.
  • Firestore and Storage security rules do the access control: anyone reads published missions, only admins write content, and learners can only create and read their own attempts.
  • One server route generates sentence audio with Google Cloud Text-to-Speech, using the Cloud Run service account.
  • Packaged with Docker and deployed to Google Cloud Run.

Challenges & what I learned

  • Checking answers fairly: splitting sentences into words while keeping contractions and hyphenated words ("o'clock", "we're") together, and ignoring case and punctuation.
  • Keeping lessons safe with security rules alone, without a backend in between, including missions that need a sign-in.
  • Working within Firestore's query limits: published missions are fetched with a single-field query and sorted in the browser to avoid extra indexes.
  • Getting AI voice audio when Gemini audio output needed an allowlist: switching to Cloud Text-to-Speech instead.
  • A clear phase plan (auth, data model, practice, admin, rules, deploy) made a two-week build predictable.
  • Firebase moves the authorization rules into the database rules, so they need the same care and testing as server code.
  • Small feedback details (marking the wrong word, hints, slow playback) matter more to learners than extra features.