Skip to content
/ talkest Public

Talkest is the "simplest" messaging app for fast, direct communication. Built with Flutter, Firebase, and Supabase, it features embedded web chat and mobile apps with real-time updates and high-priority push notifications.

License

Notifications You must be signed in to change notification settings

Khip01/talkest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

50 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Talkest.

Push Notifications

Flutter Firebase Supabase Dart Platform

Note

Update: Push notifications are finally implemented! πŸ₯³ Get notified instantly when someone reaches out through your website.

A simple real-time messaging app built with Flutter, Firebase (Auth, Cloud Firestore) and Supabase (Edge Functions, Database) - designed for a single purpose: let people reach you directly from your personal website.

No need to share social media links. No need for third-party contact forms.
Just embed Talkest on your website, and anyone with a Google account can start a conversation with you instantly.

Why does this exist?
I built Talkest because I wanted a simple "get in touch" solution for my portfolio website. Instead of redirecting visitors to social media, they can just chat with me right there, powered by a Flutter Web widget embedded directly into the page.

✨ Features

  • Real-time messaging β€” Powered by Cloud Firestore with live message streaming
  • Google Sign-In β€” One-tap authentication, no extra account needed
  • Light & Dark theme β€” With system theme detection and manual toggle
  • QR Code profile β€” Each user gets a personal QR code for quick contact sharing
  • QR Scanner β€” Scan someone's QR code to start a chat instantly
  • Start chat by email β€” Find and message any registered user by their email address
  • Editable display name β€” Customize how your name appears to others
  • Embeddable chat widget β€” Deploy the Flutter Web build and embed it on any website via iframe
  • Native mobile app β€” Install the Android app to monitor and reply to incoming messages on the go
  • Push Notifications β€” High-priority alerts with heads-up display, custom sounds, and auto-dismissal when chat is read.
  • Deep Linking β€” Clicking a notification takes you directly to the relevant chat room.

πŸ“¦ Available Platforms

Platform Status Link
Android βœ… Available Github release
Web βœ… Available khip01.github.io/talkest
Embedded mode βœ… Available Used on my portfolio
iOS ❌ Not yet No Mac device available for development

πŸ“Έ Screenshots

Mobile App

Login Chat List Messaging
Login Screen Chat List Chat Detail

Embedded Mode (on website)

Embed mode β€” Landing page on portfolio website
Embed Landing Page
Embed mode β€” Chat view on portfolio website
Embed Chat View

πŸ›  Tech Stack

Category Technology
Framework Flutter (Dart)
Backend (Primary) Firebase (Auth, Cloud Firestore)
Backend (Functions) Supabase (Edge Functions, Database)
Push Notifications Firebase Cloud Messaging (FCM v1)
Authentication Google Sign-In
State Management BLoC + Provider
Routing GoRouter
Deployment GitHub Pages (Web), APK (Android)

πŸ”§ Development Setup

Prerequisites

  • Flutter SDK
  • Firebase project with Authentication and Cloud Firestore enabled
  • Google OAuth 2.0 Client ID (for Flutter Web only)

Firestore Structure

Collections and documents are created automatically when the app runs for the first time β€” no manual setup needed. Below is the database structure for reference:

β”œβ”€β”€ app_users (collection)
β”‚   └── {uid} (document)
β”‚       β”œβ”€β”€ name: string
β”‚       β”œβ”€β”€ displayName: string
β”‚       β”œβ”€β”€ email: string
β”‚       β”œβ”€β”€ photoUrl: string
β”‚       β”œβ”€β”€ provider: string
β”‚       β”œβ”€β”€ createdAt: timestamp
β”‚       β”œβ”€β”€ updatedAt: timestamp
β”‚       └── lastLoginAt: timestamp
β”‚
└── chats (collection)
    └── {chatId} (document)
        β”œβ”€β”€ type: string ("direct")
        β”œβ”€β”€ participants: array [uid1, uid2]
        β”œβ”€β”€ createdAt: timestamp
        β”œβ”€β”€ updatedAt: timestamp
        β”œβ”€β”€ unreadCount: map { uid1: number, uid2: number }
        β”œβ”€β”€ lastMessage: map
        β”‚   β”œβ”€β”€ id: string
        β”‚   β”œβ”€β”€ senderId: string
        β”‚   β”œβ”€β”€ text: string
        β”‚   β”œβ”€β”€ type: string
        β”‚   β”œβ”€β”€ createdAt: timestamp
        β”‚   └── isDeleted: boolean
        β”‚
        └── πŸ“ messages (subcollection)
            └── {messageId} (document)
                β”œβ”€β”€ id: string
                β”œβ”€β”€ chatId: string
                β”œβ”€β”€ senderId: string
                β”œβ”€β”€ type: string
                β”œβ”€β”€ text: string
                β”œβ”€β”€ createdAt: timestamp
                β”œβ”€β”€ editedAt: timestamp (optional)
                β”œβ”€β”€ isDeleted: boolean
                β”œβ”€β”€ replyToId: string (optional)
                β”œβ”€β”€ replyToSenderId: string (optional)
                β”œβ”€β”€ replyToSenderName: string (optional)
                └── replyToText: string (optional)

Firestore Security Rules

Security rules are defined in firestore.rules.

Important

The included rules are stricter than the default test-mode rules. They enforce that:

  • Users can only write to their own profile
  • Only chat participants can read/write chats and messages
  • Messages can only be created (no editing or deleting from client)

Review and adjust the rules in firestore.rules to fit your needs before deploying.

Firestore Indexes

This project requires a composite index for querying chats. The index configuration is defined in firestore.indexes.json.

Collection Fields Query Scope
chats participants (Array) + updatedAt (Descending) Collection

Tip

If you skip deploying indexes, Firestore will show an error with a direct link to create the required index when the app first runs a query that needs it.

Deploying Firestore Rules & Indexes

Deploy both rules and indexes at once:

firebase deploy --only firestore --project YOUR_PROJECT_ID

Or deploy them individually if needed:

firebase deploy --only firestore:rules --project YOUR_PROJECT_ID
firebase deploy --only firestore:indexes --project YOUR_PROJECT_ID

Tip

If you skip this step, Firestore will show an error with a direct link to create the required index when the app first runs a query that needs it.

Getting OAuth 2.0 Client ID

  1. Via Firebase Console (Recommended):

    • Open Firebase Console
    • Select your project β†’ Project Settings
    • Add a Web app (if not already added)
    • The Client ID will be auto-generated in Google Cloud Console
  2. Manual Setup:

    • Go to Google Cloud Console
    • Navigate to APIs & Services β†’ Credentials
    • Create OAuth client ID β†’ Select Web application
    • Configure:
      • Authorized JavaScript origins:
        • http://localhost
        • http://localhost:5000
        • https://your-domain.firebaseapp.com (production)
      • Authorized redirect URIs:
        • https://your-domain.firebaseapp.com/__/auth/handler
    • Copy the generated Client ID

Supabase Structure (PostgreSQL)

The profiles table in Supabase is used to sync FCM tokens for notification delivery:

create table profiles (
  id uuid references auth.users on delete cascade,
  email text unique,
  fcm_token text,
  updated_at timestamp with time zone,
  primary key (id)
);

Push Notification Setup (Supabase - Edge Functions)

Talkest uses Supabase Edge Functions to trigger FCM v1.

  1. Service Account: Place your Firebase Service Account JSON in the Edge Function environment.
  2. Environment Variables: Set up the following in your Supabase project:
    • FIREBASE_SERVICE_ACCOUNT: Your JSON key.
  3. Deployment:
    supabase functions deploy send-notification

Running the App

Web (Development):

flutter run -d chrome \
  --dart-define=GOOGLE_WEB_CLIENT_ID=YOUR_CLIENT_ID.apps.googleusercontent.com \
  --dart-define=SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

Mobile (Android/iOS):

flutter run -d <device-id> \
  --dart-define=SUPABASE_ANON_KEY=YOUR_SUPABASE_KEY

Building for Production:

Web (Release)

flutter build web --release \
  --dart-define=GOOGLE_WEB_CLIENT_ID=YOUR_WEB_ID.apps.googleusercontent.com \
  --dart-define=SUPABASE_ANON_KEY=YOUR_SUPABASE_KEY

Important

Web builds require the Google Web Client ID for authentication.

Mobile (Release)

flutter build --release \
  --dart-define=SUPABASE_ANON_KEY=YOUR_SUPABASE_KEY

Important

Mobile builds now require the SUPABASE_ANON_KEY to sync FCM tokens and send notifications.

Embed Mode

Talkest supports an embedded chat widget mode, designed to be loaded inside an <iframe> on any website. This allows visitors to chat with a specific user directly from your page.

URL format:

https://your-talkest-deployment.com/?embed=1&targetUid=FIREBASE_USER_UID

Example iframe usage:

<iframe
  src="https://khip01.github.io/talkest/?embed=1&targetUid=YOUR_FIREBASE_UID"
  width="400"
  height="600"
  style="border: none; border-radius: 12px;"
  allow="clipboard-read; clipboard-write"
></iframe>

Parameters:

Parameter Required Description
embed Yes Set to 1 to activate embedded mode
targetUid Yes The Firebase UID of the user to chat with

Tip

You can find your Firebase UID in the Firebase Console β†’ Authentication β†’ Users tab.

In embed mode, the app will:

  • Show a landing page with a sign-in prompt for unauthenticated visitors
  • Automatically open a direct chat with the target user after sign-in
  • Hide navigation elements like the FAB and profile access for a clean widget experience

πŸ“š Resources


Made with 🀍 by Khip01

About

Talkest is the "simplest" messaging app for fast, direct communication. Built with Flutter, Firebase, and Supabase, it features embedded web chat and mobile apps with real-time updates and high-priority push notifications.

Topics

Resources

License

Stars

Watchers

Forks

Languages