Skip to content

Commit

Permalink
fix: Database access and DataStorage rules (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
mirland authored Dec 18, 2024
1 parent d8b5bfa commit 2a3cac1
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 44 deletions.
4 changes: 1 addition & 3 deletions lib/core/interfaces/db_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ abstract interface class DbInterface<T> {
Future<void> insert({
required String id,
required T data,
required String createdBy,
});

Future<List<T>?> getAllData(String createdBy);
Future<List<T>?> getAllData();

Future<T?> getData(String id);

Expand All @@ -14,7 +13,6 @@ abstract interface class DbInterface<T> {
Future<void> update({
required String id,
required T data,
required String createdBy,
});

Future<void> close();
Expand Down
10 changes: 3 additions & 7 deletions lib/core/repository/player_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,42 @@ class PlayerRepository {
final UserRemoteSource _userRemoteSource;
final AuthLocalSource _authLocalSource;

final Stock<String, List<Player>?> _store;
final Stock<void, List<Player>?> _store;
final defaultId = 'default';

PlayerRepository(this._userRemoteSource, this._authLocalSource)
: _store = Stock(
fetcher: Fetcher.ofFuture(
(createdBy) => _userRemoteSource.getAllUsers(createdBy),
(_) => _userRemoteSource.getAllUsers(),
),
);

Stream<List<Player>?> getPlayers() {
final userTokenStream = _authLocalSource.getUserToken();
return userTokenStream.switchMap(
(createdBy) => _store
.stream(createdBy ?? defaultId)
.stream(null)
.where((event) => event.isData)
.map((event) => event.requireData()),
);
}

Future<Result<Player>> setPlayer(Player player) =>
Result.fromFuture(() async {
final userId = await _authLocalSource.getUserToken().first;
await _userRemoteSource.createUser(
player.email,
player,
userId ?? defaultId,
);
await _authLocalSource.saveCurrentPlayer(player);
return player;
});

Future<Result<void>> updatePoints(int points) => Result.fromFuture(() async {
final userId = await _authLocalSource.getUserToken().first;
final player =
(await getCurrentPlayer().first)!.copyWith(points: points);
await _userRemoteSource.updateUser(
player.email,
player,
userId ?? defaultId,
);
await _authLocalSource.saveCurrentPlayer(player);
});
Expand Down
42 changes: 18 additions & 24 deletions lib/core/services/firestore_db.dart
Original file line number Diff line number Diff line change
@@ -1,64 +1,58 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:simon_ai/core/interfaces/db_interface.dart';

interface class FirestoreRankingDb
implements DbInterface<Map<String, dynamic>> {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;

final String collection;
final String subCollection;
final defaultId = 'default';

FirestoreRankingDb({
required this.collection,
required this.subCollection,
});

CollectionReference<Map<String, dynamic>> _getCollectionReference() {
final user = _auth.currentUser;
return _firestore
.collection(collection)
.doc(user?.uid ?? defaultId)
.collection(subCollection);
}

@override
Future<void> close() async => _firestore.terminate();

@override
Future<void> delete(String id) =>
_firestore.collection(collection).doc(id).delete();
Future<void> delete(String id) => _getCollectionReference().doc(id).delete();

@override
Future<List<Map<String, dynamic>>> getAllData(String createdBy) async {
final snapshot = await _firestore
.collection(collection)
.doc(createdBy)
.collection(subCollection)
.get();
Future<List<Map<String, dynamic>>> getAllData() async {
final snapshot = await _getCollectionReference().get();
return snapshot.docs.map((doc) => doc.data()).toList();
}

@override
Future<void> insert({
required String id,
required Map<String, dynamic> data,
required String createdBy,
}) =>
_firestore
.collection(collection)
.doc(createdBy)
.collection(subCollection)
.doc(id)
.set(data);
_getCollectionReference().doc(id).set(data);

@override
Future<void> update({
required String id,
required Map<String, dynamic> data,
required String createdBy,
}) =>
_firestore
.collection(collection)
.doc(createdBy)
.collection(subCollection)
.doc(id)
.update(data);
_getCollectionReference().doc(id).update(data);

@override
Future<Map<String, dynamic>?> getData(String id) async {
final snapshot = await _firestore.collection(collection).doc(id).get();
Future<Map<String, dynamic>?> getData(String userId) async {
final snapshot = await _getCollectionReference().doc(userId).get();
if (snapshot.exists) {
return snapshot.data();
}
Expand Down
13 changes: 4 additions & 9 deletions lib/core/source/user_remote_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,28 @@ class UserRemoteSource {

UserRemoteSource();

Future<void> createUser(String id, Player data, String createdBy) async {
Future<void> createUser(String id, Player data) async {
await _firestoreDb.insert(
id: id,
data: data.toJson(),
createdBy: createdBy,
);
}

Future<Player?> getUser(String id) => _firestoreDb
.getData(id)
.then((value) => value == null ? null : Player.fromJson(value));

Future<void> updateUser(String id, Player data, String createdBy) =>
_firestoreDb.update(
Future<void> updateUser(String id, Player data) => _firestoreDb.update(
id: id,
data: data.toJson(),
createdBy: createdBy,
);

Future<void> deleteUser(String id) async {
await _firestoreDb.delete(id);
}

Future<List<Player>> getAllUsers(String createdBy) async =>
(await _firestoreDb.getAllData(createdBy))
.map((e) => Player.fromJson(e))
.toList();
Future<List<Player>> getAllUsers() async =>
(await _firestoreDb.getAllData()).map((e) => Player.fromJson(e)).toList();

Future<void> close() => _firestoreDb.close();
}
1 change: 0 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ flutter:
generate: true
uses-material-design: true
assets:
- assets/images/
- assets/models/
- assets/audio/
- environments/
Expand Down

0 comments on commit 2a3cac1

Please sign in to comment.