Wed, Sep 27, 2023
Read in 2 minutes
To enforce that a user is logged in on only one device at a time using Flutter with Firebase Authentication, you can use Firebase Realtime Database or Firestore to store the user's session information. Here’s a step-by-step guide on how you can achieve this:
pubspec.yaml
.When a user logs in, generate a unique session ID and store it in Firestore/Realtime Database along with the user’s UID.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// Import 'package:firebase_database/firebase_database.dart'; // For Realtime Database
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// final FirebaseDatabase _database = FirebaseDatabase.instance; // For Realtime Database
User? user = _auth.currentUser;
if (user != null) {
String sessionID = _generateSessionID(); // Implement a function to generate a unique session ID.
// Store the sessionID in Firestore.
_firestore.collection('sessions').doc(user.uid).set({
'sessionID': sessionID,
});
// Alternatively, for Realtime Database.
// _database.reference().child('sessions/${user.uid}').set({
// 'sessionID': sessionID,
// });
}
Create a listener to monitor changes to the session information. If the session ID in the database does not match the current session ID, log the user out.
StreamSubscription<DocumentSnapshot>? sessionSubscription;
// StreamSubscription<DataSnapshot>? sessionSubscription; // For Realtime Database
if (user != null) {
// Listen for changes in Firestore.
sessionSubscription = _firestore.collection('sessions').doc(user.uid).snapshots().listen((snapshot) {
if (snapshot.exists) {
String storedSessionID = snapshot.get('sessionID');
if (storedSessionID != currentSessionID) {
_auth.signOut();
}
}
});
// Alternatively, for Realtime Database.
// sessionSubscription = _database.reference().child('sessions/${user.uid}').onValue.listen((event) {
// DataSnapshot snapshot = event.snapshot;
// String storedSessionID = snapshot.value['sessionID'];
// if (storedSessionID != currentSessionID) {
// _auth.signOut();
// }
// });
}
// Make sure to cancel the subscription when it is no longer needed.
@override
void dispose() {
sessionSubscription?.cancel();
super.dispose();
}
When a user logs out, clean up the session information from the Firestore/Realtime Database.
await _auth.signOut();
// Remove the session information from Firestore/Realtime Database.
_firestore.collection('sessions').doc(user.uid).delete();
// _database.reference().child('sessions/${user.uid}').remove(); // For Realtime Database
This approach allows you to ensure that a user is only logged in on one device at a time by tracking session information in Firebase and actively monitoring for any discrepancies.