1

I've been trying to achieve online status in my FlutterFlow app by using Flutter and Firestore. (not Realtime Database)

On addition to AppLifeCycleState conditions below, I need to add these 2 conditions:

  1. if user is logged in, set status to "online"
  2. if user is logged out, set status to "offline"
class OnlineStatus extends StatefulWidget {
  const OnlineStatus({
    super.key,
    required this.userId,
  });

  final String userId;

  @override
  State<OnlineStatus> createState() => _OnlineStatusState();
}

class _OnlineStatusState extends State<OnlineStatus>
    with WidgetsBindingObserver {
  String _userStatus = 'offline';

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _updateUserStatus('online');
    _listenToUserStatus();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      _updateUserStatus('offline');
    } else if (state == AppLifecycleState.resumed) {
      _updateUserStatus('online');
    }
  }

  Future<void> _updateUserStatus(String status) async {
    await FirebaseFirestore.instance
        .collection('Users')
        .doc(widget.userId)
        .update({'status': status});
  }

  void _listenToUserStatus() {
    FirebaseFirestore.instance
        .collection('Users')
        .doc(widget.userId)
        .snapshots()
        .listen((snapshot) {
      setState(() {
        _userStatus = snapshot.data()?['status'] ?? 'offline';
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return _buildStatusCircle();
  }

  Widget _buildStatusCircle() {
    Color circleColor = (_userStatus == 'online') ? Colors.green : Colors.red;
    return Container(
      width: 12,
      height: 12,
      decoration: BoxDecoration(
        color: circleColor,
        shape: BoxShape.circle,
      ),
    );
  }
}

I was using AppLifecycleState.detached for changing status to "offline" but it wasn't working so I had to change it to AppLifecycleState.inactive. Would also love to know why it didn't work.

Also wonder if using Firestore Database would be a big loss compared to Realtime Database.

I tried adding a condition something like FirebaseAuth.instance.currentUser != null but didn't work.

Although my code seems to be working I'm just not sure if this is the best way to do this so I can take feedback to change it.

7
  • Some AppLifecycleState values behaves differently depending on the platform so is important you check that out. Firestore was created mainly to manage complex data structures and complex queries so in this case the Realtime DB is a good solution. With Firebase Authentication, you don't lose the user's authentication state even if the app is put in the background firebase.google.com/docs/auth/flutter/… We can give you more specific ideas if you explain how the online/offline state is used and who can access that information.. Commented Jul 9, 2024 at 14:47
  • It's just a basic indicator displayed in user's profiles just like in any other social media or chatting apps. My problem in other words is that when user logs out and gets redirected to login screen, they still remain online in their profile when displayed by others. Commented Jul 9, 2024 at 16:40
  • I understand. There are a few things to consider. In my opinion, you should revisit how you manage this scenario. Based on your current approach, it's crucial to check the user's login status not only when the app is open. However, the most important point is that your _listenToUserStatus method only listens to one user document. This becomes inefficient if you have hundreds of users. Here's my suggestion: utilize Realtime Database. With Realtime Database, you can create a public zone for user statuses and establish a single listener for your entire application Commented Jul 9, 2024 at 18:37
  • I might have to go that direction if I don't get a solution soon. Is there any material aside from official documentations you can offer me since it could be a little challenging using realtime db with FlutterFlow. Commented Jul 9, 2024 at 20:57
  • Sorry I don't know exactly how FlutterFlow works. Try this, use the same code you have but inside the method _updateUserStatus instead of changing the status value on the user's Document, write that change on a single public Document with only users ids and status. Then, in your _listenToUserStatus method listen to that document ( not to the user's Document). You have to use the snapshots of that public Document to update the widget indicator.. Commented Jul 9, 2024 at 21:55

1 Answer 1

0

I am quite new to ff, so there must be a cleaner way to get it done, I would use an app state and a timer hidden on pages, when you go from a page to another you start the timer and when it is over it would reset the app state to offline and the login or whatever would set it to online

Sign up to request clarification or add additional context in comments.

1 Comment

That would be one way to do it but not sure if it's the cleanest, I've just added simple actions to change the status when loggin in/out and kept the code above same but you're right I don't think this is also the best way to achieve this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.