friends_service.dart 4.5 KB

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