Supabase: Type of expression is ambiguous without more context

244 Views Asked by At

I have spent more time than I would like to admit on this bug and any help would be appreciated.

The bug occurs in this line of code in the fetchUserData() function

guard let userId = supabase.auth.user()?.id as? String else {

Here is the HomeViewModel.swift file

import Foundation
import SwiftUI
import Combine
import Supabase

class HomeViewModel: ObservableObject {
    @Published var username: String = ""
    private var cancellables = Set<AnyCancellable>()
    private let userDataAccess: UserDataAccess
    private let supabase = SupabaseClient(supabaseURL: URL(string: Config.supabaseURL)!, supabaseKey: Config.supabaseKey)

    init() {
        userDataAccess = UserDataAccess(supabase: supabase)
        fetchUserData()
    }

    private func fetchUserData() {
        guard let userId = supabase.auth.user()?.id as? String else {
            return
        }

        userDataAccess.retrieveUserData(user_id: userId) { [weak self] result in
            DispatchQueue.main.async {
                switch result {
                case .success(let userData):
                    self?.username = userData.display_name
                case .failure(let error):
                    print("Failed to fetch user data: \(error)")
                }
            }
        }
    }
}

Here is the UserDataAccess file

import Supabase
import Foundation

class UserDataAccess {
    private let supabase: SupabaseClient

    init(supabase: SupabaseClient) {
        self.supabase = supabase
    }
    
    func retrieveUserData(user_id: String, completion: @escaping (Result<UserData, Error>) -> Void) {
        let query = supabase.database
            .from("user_data")
            .select(columns: "*")
            .filter(column: "user_id", operator: .eq, value: user_id)
            .single()

        Task {
            do {
                let response: UserData = try await query.execute().value
                completion(.success(response))
            } catch {
                completion(.failure(error))
            }
        }
    }

    func insertUserData(userData: UserData, completion: @escaping (Result<UserData, Error>) -> Void) {
        do {
            let encoder = JSONEncoder()
            let jsonData = try encoder.encode(userData)
            if let jsonObject = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {
                let encodableObject = jsonObject.mapValues { AnyEncodable($0) }
                let query = supabase.database
                    .from("user_data")
                    .insert(values: encodableObject, returning: .representation)
                    .single()

                Task {
                    do {
                        let response: UserData = try await query.execute().value
                        completion(.success(response))
                    } catch {
                        completion(.failure(error))
                    }
                }
            } else {
                completion(.failure(NSError(domain: "InsertUserDataError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to convert userData to JSON"])))
            }
        } catch {
            completion(.failure(error))
        }
    }
}

Here is the UserData file

import Foundation

struct UserData: Codable {
    let user_id: String
    let display_name: String
    let age: Int
    let gender: String
    let height: Double?
    let weight: Double?
    let fitness_goal: String

    enum CodingKeys: String, CodingKey {
        case user_id = "user_id"
        case display_name = "display_name"
        case age = "age"
        case gender = "gender"
        case height = "height"
        case weight = "weight"
        case fitness_goal = "fitness_goal"
    }
}

Thank you very much

0

There are 0 best solutions below