ds_easy_db_firebase_realtime 1.0.1 copy "ds_easy_db_firebase_realtime: ^1.0.1" to clipboard
ds_easy_db_firebase_realtime: ^1.0.1 copied to clipboard

Firebase Realtime Database implementation for DS-EasyDB. Provides real-time data synchronization with streaming support.

EasyDB Firebase Realtime #

Firebase Realtime Database implementation for DS-EasyDB (https://github.com/Dragon-InterActive/ds_easy_db). Provides real-time data synchronization with streaming support for Flutter applications.

Features #

  • Real-Time Synchronization: Instant data updates across all connected clients
  • Streaming Support: Built-in reactive streams for live data
  • Offline Support: Automatic data caching and synchronization when back online
  • Low Latency: Optimized for speed with minimal delay
  • JSON-Based: Simple JSON structure for easy data modeling
  • Cross-Platform: Works on iOS, Android, Web, macOS, Windows

Installation #

Add to your pubspec.yaml:

dependencies:
  ds_easy_db: ^1.0.1
  ds_easy_db_firebase_realtime: ^1.0.1
  firebase_core: ^4.2.1  # Required for Firebase initialization

Firebase Setup #

1. Create Firebase Project #

  1. Go to Firebase Console
  2. Create a new project or select existing one
  3. Enable Realtime Database in the "Build" section
  4. Choose a database location (closest to your users)
  5. Start in test mode (configure security rules later)

2. Install Firebase CLI #

npm install -g firebase-tools
dart pub global activate flutterfire_cli

3. Configure Firebase #

# Login to Firebase
firebase login

# Configure FlutterFire
flutterfire configure

This creates firebase_options.dart with your Firebase configuration.

Usage #

Basic Setup #

In your ds_easy_db_config.dart:

import 'package:ds_easy_db/ds_easy_db.dart';
import 'package:ds_easy_db_firebase_realtime/ds_easy_db_firebase_realtime.dart';
import 'firebase_options.dart'; // Your generated Firebase config

class EasyDBConfig {
  static DatabaseStreamRepository get stream => FirebaseRealtimeDatabase(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  // ... other configurations
}

In your main.dart:

import 'package:flutter/material.dart';
import 'package:ds_easy_db/ds_easy_db.dart';
import 'ds_easy_db_config.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Configure EasyDB
  db.configure(
    stream: EasyDBConfig.stream,
    // ... other configurations
  );
  
  // Firebase is automatically initialized when db.init() is called
  await db.init();
  
  runApp(MyApp());
}

Examples #

Watch Single Document #

// Listen to user changes in real-time
db.stream.watch('users', 'user123').listen((userData) {
  if (userData != null) {
    print('User updated: ${userData['name']}');
  } else {
    print('User deleted');
  }
});

Watch Entire Collection #

// Listen to all users
db.stream.watchAll('users').listen((allUsers) {
  if (allUsers != null) {
    print('Total users: ${allUsers.length}');
  }
});

Watch with Query #

// Watch only online users
db.stream.watchQuery('users', 
  where: {'online': true}
).listen((onlineUsers) {
  print('Online users: ${onlineUsers.length}');
  for (var user in onlineUsers) {
    print('- ${user['name']} is online');
  }
});

Write Data #

// Create or update user
await db.stream.set('users', 'user123', {
  'name': 'John Doe',
  'online': true,
  'lastSeen': DatabaseRepository.serverTS, // Uses ServerValue.timestamp
});

// Update specific fields
await db.stream.update('users', 'user123', {
  'online': false,
  'lastSeen': DatabaseRepository.serverTS,
});

// Delete user
await db.stream.delete('users', 'user123');

Real-Time Chat Example #

class ChatScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Map<String, dynamic>>>(
      stream: db.stream.watchQuery('messages',
        where: {'roomId': 'room123'}
      ),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }

        final messages = snapshot.data!;
        return ListView.builder(
          itemCount: messages.length,
          itemBuilder: (context, index) {
            final message = messages[index];
            return ListTile(
              title: Text(message['text']),
              subtitle: Text(message['sender']),
            );
          },
        );
      },
    );
  }
}

// Send message
Future<void> sendMessage(String text) async {
  await db.stream.set('messages', DateTime.now().millisecondsSinceEpoch.toString(), {
    'text': text,
    'sender': 'user123',
    'roomId': 'room123',
    'timestamp': DatabaseRepository.serverTS,
  });
}

Presence System #

// Set user online
await db.stream.set('presence', userId, {
  'online': true,
  'lastSeen': DatabaseRepository.serverTS,
});

// Watch user presence
db.stream.watch('presence', userId).listen((presence) {
  if (presence?['online'] == true) {
    print('User is online');
  } else {
    print('User was last seen at: ${presence?['lastSeen']}');
  }
});

// Set offline on disconnect (use Firebase SDK directly)
FirebaseDatabase.instance
  .ref('presence/$userId')
  .onDisconnect()
  .update({'online': false, 'lastSeen': ServerValue.timestamp});

Live Counter #

class LiveCounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<Map<String, dynamic>?>(
      stream: db.stream.watch('counters', 'visitors'),
      builder: (context, snapshot) {
        final count = snapshot.data?['count'] ?? 0;
        
        return Column(
          children: [
            Text('Visitors: $count'),
            ElevatedButton(
              onPressed: () async {
                await db.stream.update('counters', 'visitors', {
                  'count': count + 1,
                });
              },
              child: Text('Increment'),
            ),
          ],
        );
      },
    );
  }
}

Live Location Tracking #

// Update location
await db.stream.update('locations', userId, {
  'lat': 52.5200,
  'lng': 13.4050,
  'timestamp': DatabaseRepository.serverTS,
});

// Watch all locations
db.stream.watchAll('locations').listen((locations) {
  if (locations != null) {
    locations.forEach((userId, location) {
      print('$userId is at: ${location['lat']}, ${location['lng']}');
    });
  }
});

Security Rules #

Configure Firebase Realtime Database security rules in Firebase Console:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null",
        ".write": "auth != null && auth.uid == $uid"
      }
    },
    "messages": {
      ".read": "auth != null",
      ".write": "auth != null"
    },
    "presence": {
      "$uid": {
        ".read": true,
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

Data Structure Best Practices #

✅ Good Structure (Flat & Denormalized) #

// Users
await db.stream.set('users', 'user123', {
  'name': 'John',
  'email': 'john@example.com',
});

// User posts (separate collection)
await db.stream.set('posts/user123', 'post1', {
  'title': 'Hello World',
  'content': 'My first post',
});

❌ Bad Structure (Deeply Nested) #

// Don't do this!
await db.stream.set('users', 'user123', {
  'name': 'John',
  'posts': {
    'post1': {
      'title': 'Hello',
      'comments': {
        'comment1': {...}  // Too deep!
      }
    }
  }
});

Offline Support #

Realtime Database automatically caches data:

// Enable offline persistence (enabled by default)
FirebaseDatabase.instance.setPersistenceEnabled(true);

// Data is automatically synced when connection is restored
await db.stream.set('users', 'user123', {
  'name': 'John',
  'lastUpdated': DatabaseRepository.serverTS,
});

Performance Tips #

  1. Keep Data Flat: Avoid deep nesting (max 32 levels)
  2. Denormalize Data: Duplicate data for faster reads
  3. Use Indexing: Define indexes in Firebase Console for queries
  4. Limit Listeners: Don't watch entire large collections
  5. Use Priority: Set priorities for sorting without reading all data

Realtime vs Firestore #

Feature Realtime Database Firestore
Data Model JSON tree Document collections
Latency Lower Slightly higher
Queries Limited More powerful
Offline Automatic Automatic
Pricing Per GB Per operation
Best For Real-time apps Complex queries

When to Use #

✅ Perfect for Realtime Database #

  • Chat applications
  • Live tracking (location, status)
  • Collaborative editing
  • Real-time gaming
  • Presence systems
  • Live counters/metrics
  • Social feeds

❌ Consider Firestore Instead #

  • Complex queries
  • Large datasets
  • Document-based data
  • Advanced filtering
  • Transactions

Limitations #

  • Data Size: 1GB free tier
  • Connections: 100 simultaneous free tier
  • Depth: Maximum 32 levels of nesting
  • Query: Limited to single orderBy per query
  • Write Size: Maximum 256MB per write

Pricing #

Firebase Realtime Database offers a generous free tier:

  • Storage: 1GB
  • Downloads: 10GB/month
  • Connections: 100 simultaneous

See Firebase Pricing for details.

Troubleshooting #

Permission Denied #

// Error: PERMISSION_DENIED
// Solution: Update security rules in Firebase Console

Data Not Syncing #

// Check connection status
FirebaseDatabase.instance.ref('.info/connected').onValue.listen((event) {
  if (event.snapshot.value == true) {
    print('Connected to Firebase');
  } else {
    print('Disconnected from Firebase');
  }
});

Slow Queries #

// Use indexing - define in Firebase Console:
// {
//   "rules": {
//     "users": {
//       ".indexOn": ["name", "age"]
//     }
//   }
// }

License #

BSD-3-Clause License - see LICENSE file for details.

Copyright (c) 2025, MasterNemo (Dragon Software)


Feel free to clone and extend. It's free to use and share.

0
likes
160
points
17
downloads

Publisher

verified publisherdragon-software.net

Weekly Downloads

Firebase Realtime Database implementation for DS-EasyDB. Provides real-time data synchronization with streaming support.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

ds_easy_db, firebase_core, firebase_database, flutter

More

Packages that depend on ds_easy_db_firebase_realtime