-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from ProximaEPFL/firestore-repositories
Add repositories for user and posts
- Loading branch information
Showing
29 changed files
with
1,263 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:flutter/foundation.dart"; | ||
import "package:proxima/models/database/user/user_id_firestore.dart"; | ||
|
||
@immutable | ||
class PostData { | ||
final UserIdFirestore ownerId; | ||
static const String ownerIdField = "ownerId"; | ||
|
||
final String title; | ||
static const String titleField = "title"; | ||
|
||
final String description; | ||
static const String descriptionField = "description"; | ||
|
||
final Timestamp publicationTime; | ||
static const String publicationTimeField = "publicationTime"; | ||
|
||
final int voteScore; | ||
static const String voteScoreField = "voteScore"; | ||
|
||
const PostData({ | ||
required this.ownerId, | ||
required this.title, | ||
required this.description, | ||
required this.publicationTime, | ||
required this.voteScore, | ||
}); | ||
|
||
/// This method will create an instance of [PostData] from the | ||
/// data map [data] that comes from firestore | ||
factory PostData.fromDbData(Map<String, dynamic> data) { | ||
try { | ||
return PostData( | ||
ownerId: UserIdFirestore(value: data[ownerIdField]), | ||
title: data[titleField], | ||
description: data[descriptionField], | ||
publicationTime: data[publicationTimeField], | ||
voteScore: data[voteScoreField], | ||
); | ||
} catch (e) { | ||
if (e is TypeError) { | ||
throw FormatException("Cannot parse post document: ${e.toString()}"); | ||
} else { | ||
rethrow; | ||
} | ||
} | ||
} | ||
|
||
/// This method will create a map from the current instance of [PostData] | ||
/// to be stored in firestore | ||
Map<String, dynamic> toDbData() { | ||
return { | ||
ownerIdField: ownerId.value, | ||
titleField: title, | ||
descriptionField: description, | ||
publicationTimeField: publicationTime, | ||
voteScoreField: voteScore, | ||
}; | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (identical(this, other)) return true; | ||
|
||
return other is PostData && | ||
other.ownerId == ownerId && | ||
other.title == title && | ||
other.description == description && | ||
other.publicationTime == publicationTime && | ||
other.voteScore == voteScore; | ||
} | ||
|
||
@override | ||
int get hashCode { | ||
return Object.hash(ownerId, title, description, publicationTime, voteScore); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:flutter/foundation.dart"; | ||
import "package:proxima/models/database/post/post_data.dart"; | ||
import "package:proxima/models/database/post/post_id_firestore.dart"; | ||
import "package:proxima/models/database/post/post_location_firestore.dart"; | ||
|
||
@immutable | ||
class PostFirestore { | ||
/// This is the collection in which the posts are stored | ||
static const collectionName = "posts"; | ||
|
||
/// The id is not stored in a field because it already | ||
/// corresponds to the document id on firestore | ||
final PostIdFirestore id; | ||
|
||
/// The post location is not stored in the [PostData] because it | ||
/// is exclusively managed by the repository (in particular, it is the | ||
/// responsability of the repository to create it when adding a post) | ||
final PostLocationFirestore location; | ||
static const String locationField = "location"; | ||
|
||
final PostData data; | ||
|
||
const PostFirestore({ | ||
required this.id, | ||
required this.location, | ||
required this.data, | ||
}); | ||
|
||
/// This method will create an instance of [PostFirestore] from the | ||
/// document snapshot [docSnap] that comes from firestore | ||
factory PostFirestore.fromDb(DocumentSnapshot docSnap) { | ||
if (!docSnap.exists) { | ||
throw Exception("Post document does not exist"); | ||
} | ||
|
||
try { | ||
final data = docSnap.data() as Map<String, dynamic>; | ||
|
||
return PostFirestore( | ||
id: PostIdFirestore(value: docSnap.id), | ||
location: PostLocationFirestore.fromDbData(data[locationField]), | ||
data: PostData.fromDbData(data), | ||
); | ||
} catch (e) { | ||
if (e is TypeError) { | ||
throw FormatException("Cannot parse post document: ${e.toString()}"); | ||
} else { | ||
rethrow; | ||
} | ||
} | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (identical(this, other)) return true; | ||
|
||
return other is PostFirestore && | ||
other.id == id && | ||
other.location == location && | ||
other.data == data; | ||
} | ||
|
||
@override | ||
int get hashCode { | ||
return Object.hash(id, location, data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import "package:flutter/foundation.dart"; | ||
|
||
/// The id are strong typed to avoid misuse | ||
@immutable | ||
class PostIdFirestore { | ||
final String value; | ||
|
||
const PostIdFirestore({required this.value}); | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
return other is PostIdFirestore && other.value == value; | ||
} | ||
|
||
@override | ||
int get hashCode => value.hashCode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:flutter/foundation.dart"; | ||
|
||
@immutable | ||
class PostLocationFirestore { | ||
final GeoPoint geoPoint; | ||
final String geohash; | ||
|
||
/// Do not change ! | ||
/// The [GeoFlutterFire] library that is used to perform the geo queries uses | ||
/// hardcoded field name values in its implementation and does not provide | ||
/// methods to automatically parse the point data. Thus we must manually specify | ||
/// the field name for the geo point and the geo hash | ||
static const String geoPointField = "geopoint"; // Do not change | ||
static const String geohashField = "geohash"; // Do not change | ||
|
||
const PostLocationFirestore({ | ||
required this.geoPoint, | ||
required this.geohash, | ||
}); | ||
|
||
/// This method will create an instance of [PostLocationFirestore] from the | ||
/// data map [data] that comes from firestore | ||
factory PostLocationFirestore.fromDbData(Map<String, dynamic> data) { | ||
try { | ||
return PostLocationFirestore( | ||
geoPoint: data[geoPointField], | ||
geohash: data[geohashField], | ||
); | ||
} catch (e) { | ||
if (e is TypeError) { | ||
throw FormatException( | ||
"Cannot parse post location document: ${e.toString()}", | ||
); | ||
} else { | ||
rethrow; | ||
} | ||
} | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (identical(this, other)) return true; | ||
|
||
return other is PostLocationFirestore && | ||
other.geoPoint == geoPoint && | ||
other.geohash == geohash; | ||
} | ||
|
||
@override | ||
int get hashCode => Object.hash(geoPoint, geohash); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:flutter/foundation.dart"; | ||
|
||
@immutable | ||
class UserData { | ||
final String username; | ||
static const String usernameField = "username"; | ||
|
||
final String displayName; | ||
static const String displayNameField = "displayName"; | ||
|
||
final Timestamp joinTime; | ||
static const joinTimeField = "joinTime"; | ||
|
||
const UserData({ | ||
required this.username, | ||
required this.displayName, | ||
required this.joinTime, | ||
}); | ||
|
||
/// This method will create an instance of [UserData] from the | ||
/// data map [data] that comes from firestore | ||
factory UserData.fromDbData(Map<String, dynamic> data) { | ||
try { | ||
return UserData( | ||
username: data[usernameField], | ||
displayName: data[displayNameField], | ||
joinTime: data[joinTimeField], | ||
); | ||
} catch (e) { | ||
if (e is TypeError) { | ||
throw FormatException( | ||
"Cannot parse user data document: ${e.toString()}", | ||
); | ||
} else { | ||
rethrow; | ||
} | ||
} | ||
} | ||
|
||
/// This method will create a map from the current instance of [UserData] | ||
/// to be stored in firestore | ||
Map<String, dynamic> toDbData() { | ||
return { | ||
usernameField: username, | ||
displayNameField: displayName, | ||
joinTimeField: joinTime, | ||
}; | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
return other is UserData && | ||
other.username == username && | ||
other.displayName == displayName && | ||
other.joinTime == joinTime; | ||
} | ||
|
||
@override | ||
int get hashCode => Object.hash(username, displayName, joinTime); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:flutter/foundation.dart"; | ||
import "package:proxima/models/database/user/user_data.dart"; | ||
import "package:proxima/models/database/user/user_id_firestore.dart"; | ||
|
||
@immutable | ||
class UserFirestore { | ||
// This is the collection where the users are stored | ||
static const collectionName = "users"; | ||
|
||
/// The uid is not stored in a field because it already | ||
/// corresponds to the document id on firestore | ||
final UserIdFirestore uid; | ||
|
||
final UserData data; | ||
|
||
const UserFirestore({required this.uid, required this.data}); | ||
|
||
/// This method will create an instance of [UserFirestore] from the | ||
/// document snapshot [docSnap] that comes from firestore | ||
factory UserFirestore.fromDb(DocumentSnapshot docSnap) { | ||
if (!docSnap.exists) { | ||
throw Exception("User document does not exist"); | ||
} | ||
|
||
try { | ||
final data = docSnap.data() as Map<String, dynamic>; | ||
|
||
return UserFirestore( | ||
uid: UserIdFirestore(value: docSnap.id), | ||
data: UserData.fromDbData(data), | ||
); | ||
} catch (e) { | ||
if (e is TypeError) { | ||
throw FormatException("Cannot parse user document : ${e.toString()}"); | ||
} else { | ||
rethrow; | ||
} | ||
} | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
return other is UserFirestore && other.uid == uid && other.data == data; | ||
} | ||
|
||
@override | ||
int get hashCode => Object.hash(uid, data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import "package:flutter/foundation.dart"; | ||
|
||
/// The id are strong typed to avoid misuse | ||
@immutable | ||
class UserIdFirestore { | ||
final String value; | ||
|
||
const UserIdFirestore({required this.value}); | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
return other is UserIdFirestore && other.value == value; | ||
} | ||
|
||
@override | ||
int get hashCode => value.hashCode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import "package:cloud_firestore/cloud_firestore.dart"; | ||
import "package:hooks_riverpod/hooks_riverpod.dart"; | ||
|
||
/// Static singleton [FirebaseFirestore] instance provider | ||
final firestoreProvider = Provider<FirebaseFirestore>( | ||
(ref) => FirebaseFirestore.instance, | ||
); |
Oops, something went wrong.