Architecture for an Android Chat Application

ArchitecturechatmessagingmongodbMySQL

I want to develop a chat application that reminds a bit whatsapp, I am doing it as a learning project. I am currently doing it on Android just because I am doing an Android course.

The requirements are:

  1. users register with some data (phone number, name)
  2. users can write messages to friends who also use the same application
  3. messages are written to DB – I think there are many writes but less reads just because that when a message is sent to the server and written to DB a notification is sent to the receiver's mobile, but maybe in the future I would also want to add web interface so it might include also many reads from DB.
  4. when message is read I want to update the DB.

I was thinking first to use MySQL for storing all users and some NoSQL for the purpose of storing the messages – MongoDB, this is because the messages data can grow to large scales very fast and using RDB might be a problem.

Do you think it will be right to use this architecture? Will MongoDB be a problem since there might be many updates? after a message was written and when the receiver's phone accepts the message an update is sent to the server indicated message received?

Maybe I am missing something that you can please think of?

If you think there is a better architecture I will appreciate if you can contribute.

Thanks.

Best Answer

Some considerations:

  1. Choice of database: relational databases such as Mysql or Postgres are not necessarily harder to scale than MongoDB and such. In many cases it's quite the opposite. Here is a great comparison of different storage technologies: http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

  2. "Event-driven" architecture: You have a lot of requirements that boil down to "when this happens, do something". A typical way to build an architecture like that is to think of events being emitted and event listeners acting upon those events. For example:

    • "message read" is an event that your Android app will be sending back to the server when somebody reads a message. Server can have a listener waiting for events like that, and every time it gets one, it'll go and mark the message as "read" in the database
    • You can think of other use cases like that: "message received" is an event - listener will take that message and forward it on to the recepient.
    • Another one: "user connected" - when somebody launches the app and connects to the server, you'd probably like to forward any messages directed to them that gathered while they were offline - that can be easily addressed using events.

You would typically have a message queue as the center piece of your application, with all kinds of listeners connected to it, and all events that are emitted sent through it.

  1. 3rd party solutions: If you are doing this as a learning exercise with focus on Android development, consider using a 3rd party solution that can take care of a lot of your backend needs. One example is https://www.firebase.com/. Building a full-blown backend system for an app like this, with serious scaling and performance requirements is a lot of effort which will take your time away from learning Android.

  2. Start simple, iterate: I'd start with a very simple back-end app without a database, and develop it in parallel with the Android app. Make sure you understand as much as possible about your requirements before you make big decisions about what database to use etc - the only real way to do that is to prototype and iterate as quickly as possible.


Now, some concrete solution "templates" that you can use as starting points:

Firebase-powered backend

Go this route if:

  • You would rather focus on learning Android and not worry about the backend
  • You favor getting something running quickly over getting your hands dirty with every part of the system at once

Firebase can take care of much of your needs. You won't need to think about the database and scaling. But you'll need to understand their data models.

Some places to start with:

Node.js + Socket.io + MongoDB + Redis

Go this route if:

  • You want to use a popular framework that fits the realtime communications requirement
  • You don't mind introducing a whole other language and set of technologies
  • You don't mind working with JavaScript

Rough outline of the system:

  • Node.js and socket.io handling all of your communication to/from Android app
  • MongoDB is used to store messages and user information
  • Redis is used as a "message queue" to connect your event emitters and event listeners

Socket.io is good at communications: you won't need to write low-level networking code. Node.js has good performance for things like that.

Pointers:

Java Netty + RabbitMQ + MongoDB

Go this route if:

  • You want to stick with Java as much as possible
  • You don't mind learning a whole lot about low level networking stuff
  • You like to understand and control as much of your infrastructure as possible

Outline:

  • Netty for network communications
  • RabbitMQ as the message queue for communications between event emitters and listeners
  • MongoDB to store messages and user information

Pointers:

Related Topic