Flutter Firebase Chat App – Part 7: Online / Offline Status System

Learn how to implement an online/offline user presence system in Flutter using Firebase Firestore to show online status and last seen timestamps.

Introduction

Presence systems allow users to see whether someone is currently online or when they were last active.

This feature improves communication and makes messaging apps feel more real-time and responsive.

In this article we will implement:

  • Online status tracking
  • Last seen timestamps
  • Firestore presence structure
  • Automatic status updates

Presence System Architecture

User opens app
      ↓
Status set to online
      ↓
User closes app
      ↓
Status set to offline
      ↓
LastSeen timestamp updated

User Document Structure

users
   ├── userId
   │      ├── name
   │      ├── profileImage
   │      ├── isOnline
   │      ├── lastSeen

Example User Document

{
  "name": "Ravi",
  "isOnline": true,
  "lastSeen": Timestamp
}

Step 1: Set User Online

When the app starts:

await FirebaseFirestore.instance
  .collection('users')
  .doc(currentUserId)
  .update({
    "isOnline": true
  });

Step 2: Set User Offline

When the app goes to background or closes:

await FirebaseFirestore.instance
  .collection('users')
  .doc(currentUserId)
  .update({
    "isOnline": false,
    "lastSeen": Timestamp.now()
  });

Using App Lifecycle

class PresenceHandler with WidgetsBindingObserver {

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {

    if (state == AppLifecycleState.resumed) {
      setOnline();
    }

    if (state == AppLifecycleState.paused) {
      setOffline();
    }

  }
}

Step 3: Show Online Status

StreamBuilder(
  stream: FirebaseFirestore.instance
    .collection('users')
    .doc(otherUserId)
    .snapshots(),
  builder: (context, snapshot) {

    if (!snapshot.hasData) return SizedBox();

    final data = snapshot.data!.data();

    bool isOnline = data['isOnline'];

    return Text(
      isOnline ? "Online" : "Offline"
    );

  },
);

Show Last Seen

Timestamp lastSeen = data['lastSeen'];

Text(
  "Last seen: ${lastSeen.toDate()}"
)

Better UI Example

if (isOnline)
  Text(
    "Online",
    style: TextStyle(color: Colors.green)
  )
else
  Text(
    "Last seen recently",
    style: TextStyle(color: Colors.grey)
  )

Optimization Tips

  • Avoid updating presence too frequently
  • Update status only when app state changes
  • Use lightweight fields

Security Rule Reminder

match /users/{userId} {
  allow update: if request.auth.uid == userId;
}

Common Beginner Mistakes

  • Updating presence on every screen
  • No lifecycle handling
  • Forgetting to update lastSeen

Production Flow Summary

User opens app
      ↓
isOnline = true
      ↓
User closes app
      ↓
isOnline = false
lastSeen = timestamp

Conclusion

Online presence is an essential feature for messaging apps.

By tracking user lifecycle events and storing presence data in Firestore, we can easily implement a reliable status system.

In the next article we will implement: Message Pagination & Infinite Scroll (Load Older Messages).

Share

What's Your Reaction?

Like Like 0
Dislike Dislike 0
Love Love 0
Funny Funny 0
Angry Angry 0
Sad Sad 0
Wow Wow 0