friends_service.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import 'package:cloud_firestore/cloud_firestore.dart';
  2. import 'package:physigo/friends/models/friend_request.dart';
  3. import '../models/friend.dart';
  4. import '../models/friend_relation.dart';
  5. const userId = "tlmysIvwTBaoZKWqBofx";
  6. class FriendsService {
  7. static final _db = FirebaseFirestore.instance;
  8. static final _friends = _db.collection("Friends");
  9. static final _users = _db.collection("Users");
  10. static Future<List<Friend>> getFriends() async {
  11. return _getFriendsByStatus(RequestStatus.accepted);
  12. }
  13. static Future<List<FriendRequest>> getPendingRequests() async {
  14. final friendRequests =
  15. await _friends.where("friend_id", isEqualTo: userId).where("request_status", isEqualTo: "pending").get();
  16. if (friendRequests.docs.isEmpty) {
  17. return [];
  18. }
  19. final friendsIdRequestsId = {for (final r in friendRequests.docs) r.data()['user_id']: r.id};
  20. final friendsInfo = await _users.where(FieldPath.documentId, whereIn: friendsIdRequestsId.keys.toList()).get();
  21. return friendsInfo.docs
  22. .map((f) => FriendRequest(
  23. requestId: friendsIdRequestsId[f.id]!,
  24. friendName: f.data()['name'],
  25. friendSurname: f.data()['surname'],
  26. ))
  27. .toList();
  28. }
  29. static Future<void> addFriend(String friendSharedId) async {
  30. try {
  31. final query = (await _users.where("shared_id", isEqualTo: friendSharedId).get());
  32. if (query.docs.isEmpty) {
  33. return Future.error("This account doesn't exist");
  34. }
  35. final friend = query.docs.first;
  36. await _checkExistingFriendRelation(friend.id);
  37. final friendRequest = {"user_id": userId, "friend_id": friend.id, "request_status": "pending"};
  38. await _friends.add(friendRequest);
  39. } catch (error) {
  40. return Future.error(error);
  41. }
  42. }
  43. static Future<void> acceptFriendRequest(FriendRequest friendRequest) async {
  44. final newStatus = {"request_status": "accepted"};
  45. await _friends.doc(friendRequest.requestId).update(newStatus);
  46. }
  47. static Future<void> refuseFriendRequest(FriendRequest friendRequest) async {
  48. final newStatus = {"request_status": "rejected"};
  49. await _friends.doc(friendRequest.requestId).update(newStatus);
  50. }
  51. static Future<List<Friend>> _getFriendsByStatus(RequestStatus status) async {
  52. final friendsByUserId = _friends.where("user_id", isEqualTo: userId).get();
  53. final friendsByFriendId = _friends.where("friend_id", isEqualTo: userId).get();
  54. final friendRelations = (await Future.wait([friendsByUserId, friendsByFriendId]))
  55. .expand((query) => query.docs)
  56. .map((friendRelation) => FriendRelation.fromMap(friendRelation.id, friendRelation.data(), userId))
  57. .where((friendRelation) => friendRelation.requestStatus == status)
  58. .toList();
  59. final friends = await _getFriendsFromFriendRelations(friendRelations);
  60. return friends;
  61. }
  62. static Future<List<Friend>> _getFriendsFromFriendRelations(List<FriendRelation> friendRelations) async {
  63. final users = await _db
  64. .collection('Users')
  65. .where(FieldPath.documentId, whereIn: friendRelations.map((e) => e.friendId).toList())
  66. .get();
  67. final friends = users.docs.map((friend) {
  68. final data = friend.data();
  69. final friendRelation = friendRelations.firstWhere((element) => element.friendId == friend.id);
  70. return Friend(
  71. id: friend.id,
  72. name: data['name'],
  73. surname: data['surname'],
  74. status: friendRelation.requestStatus,
  75. relationId: friendRelation.id,
  76. );
  77. }).toList();
  78. return friends;
  79. }
  80. static Future<void> _checkExistingFriendRelation(String friendId) async {
  81. if (friendId == userId) {
  82. return Future.error("You already are your own friend");
  83. }
  84. var friendRelation = await _db
  85. .collection("Friends")
  86. .where("user_id", isEqualTo: userId)
  87. .where("friend_id", isEqualTo: friendId)
  88. .get();
  89. if (friendRelation.docs.isNotEmpty) {
  90. return Future.error("You already sent a request to this person");
  91. }
  92. friendRelation = await _db
  93. .collection("Friends")
  94. .where("friend_id", isEqualTo: userId)
  95. .where("user_id", isEqualTo: friendId)
  96. .get();
  97. if (friendRelation.docs.isNotEmpty) {
  98. return Future.error("They already sent you a request");
  99. }
  100. }
  101. }