Baata Chat
Phone-number chat with no file-size limit
- Year
- 2022
- Kind
- Apps
- Status
- Finished
A one-to-one chat app from 2022: a Flutter client with Firebase phone sign-in and push, and a Flask server that took messages, photos and videos with no file-size limit.
Baata signs users in by phone number with Firebase Authentication and finds friends from the phone's contacts. Messages, photos and videos go to a Flask server over HTTP with no file-size limit, and a Firebase Cloud Messaging push tells the other phone to refetch. The chat list is cached on the device so the app opens instantly.
The problem
Baata is a one-to-one chat app I built in 2022, with a Flutter client and my own Flask server behind it. Messages and media have no size limit, and everything is stored in the cloud, so a conversation is there on any device.
How it works
- 01
Sign in with a phone number
Accounts are phone numbers, verified by Firebase Authentication: Firebase texts a one-time code and signs the user in once it's entered. From then on, every request to the Flask API carries the user's Firebase ID token in a jwt header, refreshed on a timer, so Baata has no passwords of its own.
- 02
Find people from your contacts
With permission, the app reads the phone's contacts and asks the server about each number. People already on Baata show their photo and status and can be messaged; everyone else gets an Invite button.
- 03
Send over HTTP, wake up over FCM
A text message is a POST to the Flask server. The app registers its Firebase Cloud Messaging (FCM) token with the server, and whenever a push arrives it refetches the open chat or the chat list over HTTP. The push is only a doorbell; the messages always come from the server.
- 04
Send photos and videos
Photos can be cropped before sending, and the video picker allows clips up to 3 hours long. Both go up as multipart form uploads with the message details alongside, and the original server put no limit on their size. Media comes back with the token in the request headers: images through CachedNetworkImage, which keeps a copy on disk, and video streamed straight into the player.
- 05
Open from cache, then refresh
After every fetch the chat list is saved to SharedPreferences, the phone's small key-value store. Opening the app shows the last known conversations at once, and the network result replaces them when it arrives.
Decisions
Firebase for identity and push, my server for data
Firebase handles phone verification and push delivery. Messages, media and profiles live on the Flask server. The app never sends that server a password, only a Firebase token.
Pushes carry no content
The app ignores what's in a push and asks the server instead. The server stays the single source of truth, and a missed push only means the next refetch catches up.