Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delete friend #129

Merged
merged 6 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions Gauge/Profiles+Search/ViewModels/FriendsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,110 @@ class FriendsViewModel: ObservableObject {
return nil
}
}

enum FriendRequestError: Error {
case invalidData(reason: String)
case userError(reason:String)
}

func acceptFriendRequest(friendId: String, hostId: String) async throws {
do {
let friendDocRef = Firebase.db.collection("USERS").document(friendId)
let hostDocRef = Firebase.db.collection("USERS").document(hostId)
async let friendDocumentSnapshot = friendDocRef.getDocument()
async let hostDocumentSnapshot = hostDocRef.getDocument()

let (friendSnapshot, hostSnapshot) = try await (friendDocumentSnapshot, hostDocumentSnapshot)

// remove hostId from friend's outgoing requests
guard let friendDocument = friendSnapshot.data() else {
throw FriendRequestError.invalidData(reason: "Friend document not found")
}
guard var friendsOut = friendDocument["friendOut"] as? [String: [String]] else { throw FriendRequestError.invalidData(reason: "No outgoing request data for friend")}
guard friendsOut.removeValue(forKey: hostId) != nil else {
throw FriendRequestError.invalidData(reason: "Host is not in friend's outgoing requests")
}
// remove friendId from host's incoming requests
guard let hostDocument = hostSnapshot.data() else {
throw FriendRequestError.invalidData(reason: "Host document not found")
}
guard var hostIn = hostDocument["friendIn"] as? [String: [String]] else { throw FriendRequestError.invalidData(reason: "No incoming request data for host")}
guard hostIn.removeValue(forKey: friendId) != nil else {
throw FriendRequestError.invalidData(reason: "Friend is not in host's incoming requests")
}

// add host to freind's friends
var friendFriends = friendDocument["friends"] as? [String: [String]] ?? [:]
guard let hostUsername = hostDocument["username"] as? String else { throw FriendRequestError.userError(reason: "Host document does not contain username")}
let hostProfilePhoto = hostDocument["profilePhoto"] as? String ?? ""
friendFriends[hostId] = [hostUsername, hostProfilePhoto]

// add friend to host's friends
var hostFriends = hostDocument["friends"] as? [String: [String]] ?? [:]
guard let friendUsername = friendDocument["username"] as? String else { throw FriendRequestError.userError(reason: "Friend document does not contain username")}
let friendProfilePhoto = friendDocument["profilePhoto"] as? String ?? ""
hostFriends[friendId] = [friendUsername, friendProfilePhoto]

let batch = Firebase.db.batch()
batch.updateData(["friendOut": friendsOut,"friends": friendFriends], forDocument: friendDocRef)
batch.updateData(["friendIn": hostIn, "friends": hostFriends], forDocument: hostDocRef)

try await batch.commit()
} catch FriendRequestError.invalidData(let reason) {
print("Data Error - \(reason)")
throw FriendRequestError.invalidData(reason: reason)
} catch FriendRequestError.userError(let reason) {
print("User Error - \(reason)")
throw FriendRequestError.userError(reason: reason)
}
catch {
print("Unexpected Error")
throw error
}
}

func rejectFriendRequest(friendId: String, hostId: String) async throws {
do {
let batch = Firebase.db.batch()
let friendDocRef = Firebase.db.collection("USERS").document(friendId)
let hostDocRef = Firebase.db.collection("USERS").document(hostId)
async let friendDocumentSnapshot = friendDocRef.getDocument()
async let hostDocumentSnapshot = hostDocRef.getDocument()

let (friendSnapshot, hostSnapshot) = try await (friendDocumentSnapshot, hostDocumentSnapshot)

// remove hostId from friend's outgoing requests
guard let friendDocument = friendSnapshot.data() else {
throw FriendRequestError.invalidData(reason: "Friend document not found")
}
guard var friendsOut = friendDocument["friendOut"] as? [String: [String]] else { throw FriendRequestError.invalidData(reason: "No outgoing request data for friend")}
guard friendsOut.removeValue(forKey: hostId) != nil else {
throw FriendRequestError.invalidData(reason: "Host is not in friend's outgoing requests")
}
batch.updateData(["friendOut": friendsOut], forDocument: friendDocRef)

// remove friendId from host's incoming requests
guard let hostDocument = hostSnapshot.data() else {
throw FriendRequestError.invalidData(reason: "Host document not found")
}
guard var hostIn = hostDocument["friendIn"] as? [String: [String]] else { throw FriendRequestError.invalidData(reason: "No incoming request data for host")}
guard hostIn.removeValue(forKey: friendId) != nil else {
throw FriendRequestError.invalidData(reason: "Friend is not in host's incoming requests")
}
batch.updateData(["friendIn": hostIn], forDocument: hostDocRef)

try await batch.commit()

} catch FriendRequestError.invalidData(let reason) {
print("Data Error - \(reason)")
throw FriendRequestError.invalidData(reason: reason)
} catch FriendRequestError.userError(let reason) {
print("User Error - \(reason)")
throw FriendRequestError.userError(reason: reason)
}
catch {
print("Unexpected Error")
throw error
}
}
}
18 changes: 18 additions & 0 deletions GaugeTests/GaugeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import XCTest
@testable import Gauge
import FirebaseFirestore

final class GaugeTests: XCTestCase {

Expand Down Expand Up @@ -50,4 +51,21 @@ final class GaugeTests: XCTestCase {
let user = await viewModel.getUserFromId(userId: userId)
print(user)
}


func testFriendRequest() async {
let friendUser = User(userId: "thing2", username: "dummy", email: "dummy")
let hostUser = User(userId: "thing1", username: "dummy", email: "dummy")
let viewModel = FriendsViewModel(user: hostUser)

let friendId = friendUser.id
let hostId = hostUser.id
do {
try await viewModel.acceptFriendRequest(friendId: friendId, hostId: hostId)
print("Friend request accepted successfully.")
} catch {
print("error")
}

}
}