ios – How to create a view model to upload post to firebase


I am trying to create a view model that will allow me to upload my video url, image string and a text string to firebase but the current code im using on the view model is not allowing me to upload my data to firebase none of my strings are uploadeding. How do I rewrite this code to upload my post to firebase to fix my problem ?

import SwiftUI
import Firebase
import PhotosUI
import FirebaseStorage
import FirebaseFirestoreSwift

@MainActor
class UploadPostViewModel: NSObject, ObservableObject {
  
    
    @Published var didUploadPost = false
    @Published var isLoading = false
    @Published var error: Error?
    @Published var text: String = ""
    @Published var videos = [Video]()
    @Published var mediaPreview: Movie?
    @Published var profileImage: Image?
    @Published var selectedvideoUrl: URL?
    @Published var selectedImage: PhotosPickerItem? {
        didSet { Task { await loadImage(fromItem: selectedImage)
                          Task { try await uploadVideo() }
                      } }
                  }
    
    
    private var uiImage: UIImage?
  
    func uploadPost(caption: String) async throws {
        
        guard let uid = Auth.auth().currentUser?.uid else { return }
        
        var imageUrl: String? = nil
        if let image = uiImage {
            imageUrl = try await ImageUploader.uploadImage(image: image , type: .post)
        }
            guard let item = selectedvideoUrl else {return}
            if let videoUrl = selectedvideoUrl {
                guard let videoData = try? Data(contentsOf: videoUrl) else{return}
                guard let uploadVideoUrl = try await VideoUploader.uploadVideo(withData: videoData) else { return}
                
            
            
            
            
            
            
            
            let post = Post(
                ownerUid: uid,
                text: text,
                videoUrl: uploadVideoUrl, likes: 0,replyCount: 23, imageUrl:imageUrl,
                timestamp: Timestamp()
            )
            
            try await PostService.uploadPost(post)
            self.didUploadPost = true
            
        }
        
        
    }
    
  
        func fetchVideos() async throws {
            let snapshot = try await Firestore.firestore().collection("videos").getDocuments()
            self.videos = snapshot.documents.compactMap({ try? $0.data(as: Video.self) })
        }
        func loadImage(fromItem item: PhotosPickerItem?) async {
                 guard let item = item else { return }
                 
                 guard let data = try? await item.loadTransferable(type: Data.self) else { return }
                 guard let uiImage = UIImage(data: data) else { return }
                 self.uiImage = uiImage
                 self.profileImage = Image(uiImage: uiImage)
             }

    
    func uploadVideo() {
        guard let videoURL = selectedvideoUrl else {
            return
        }
        
        let storage = Storage.storage()
        let storageRef = storage.reference()
        let videoRef = storageRef.child("videos").child("videoFileName.mp4")
        let localVideoURL = URL(fileURLWithPath: "path/to/local/video.mp4")
        let metadata = StorageMetadata()
        metadata.contentType = "video/mp4"
        
        videoRef.putFile(from: localVideoURL, metadata: nil) { metadata, error in
            guard error == nil else {
                print("Error uploading video: \(error!)")
                return
            }
            videoRef.downloadURL { url, error in
                guard let videoURL = url, error == nil else {
                    print("Error getting download URL: \(error!)")
                    return
                }

import Foundation
import Firebase
import FirebaseFirestoreSwift

struct PostService {
    
    static func uploadPost(_ post: Post) async throws {
        guard let postData = try? Firestore.Encoder().encode(post) else { return }
        do{
        let ref = try await FirestoreConstants.PostsCollection.addDocument(data: postData)
        try await updateUserFeedsAfterPost(postId: ref.documentID)
    } catch {
        print("---> \(error)")
    }
    }
    
    static func fetchPost(withId id: String) async throws -> Post {
        let postSnapshot = try await FirestoreConstants.PostsCollection.document(id).getDocument()
        let post = try postSnapshot.data(as: Post.self)
        return post
    }
    
    static func fetchUserPosts(user: Userss) async throws -> [Post] {
        let snapshot = try await FirestoreConstants.PostsCollection.whereField("ownerUid", isEqualTo: user.id).getDocuments()
        var posts = snapshot.documents.compactMap({try? $0.data(as: Post.self )})
        
        for i in 0 ..< posts.count {
            posts[i].user = user
        }
        
        return posts
    }
}

// MARK: - Likes

extension PostService {
    static func likePost(_ post: Post) async throws {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        guard let postId = post.id else { return }
        
        async let _ = try await FirestoreConstants.PostsCollection.document(postId).collection("post-likes").document(uid).setData([:])
        async let _ = try await FirestoreConstants.PostsCollection.document(postId).updateData(["likes": post.likes + 1])
        async let _ = try await FirestoreConstants.UserCollection.document(uid).collection("user-likes").document(postId).setData([:])
        
       
    }
    
    static func unlikePost(_ post: Post) async throws {
        guard post.likes > 0 else { return }
        guard let uid = Auth.auth().currentUser?.uid else { return }
        guard let postId = post.id else { return }
        
        async let _ = try await FirestoreConstants.PostsCollection.document(postId).collection("post-likes").document(uid).delete()
        async let _ = try await FirestoreConstants.UserCollection.document(uid).collection("user-likes").document(postId).delete()
        async let _ = try await FirestoreConstants.PostsCollection.document(postId).updateData(["likes": post.likes - 1])
        
       
    }
    
    static func checkIfUserLikedPost(_ post: Post) async throws -> Bool {
        guard let uid = Auth.auth().currentUser?.uid else { return false }
        guard let postId = post.id else { return false }
        
        let snapshot = try await FirestoreConstants.UserCollection.document(uid).collection("user-likes").document(postId).getDocument()
        return snapshot.exists
    }
}

// MARK: - Feed Updates

extension PostService {
    private static func updateUserFeedsAfterPost(postId: String) async throws {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        
        let followersSnapshot = try await FirestoreConstants.FollowersCollection.document(uid).collection("user-followers").getDocuments()
        
        for document in followersSnapshot.documents {
            try await FirestoreConstants
                .UserCollection
                .document(document.documentID)
                .collection("user-feed")
                .document(postId).setData([:])
        }
        
        try await FirestoreConstants.UserCollection.document(uid).collection("user-feed").document(postId).setData([:])
    }
}

        }
    

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img