I initially asked this question, got the answer, and in the comments @LeoDabus said:
NSData(contentsOf: url) it is not mean to use with non local resources urls
He suggested I use URLSession which I did, but the response is very slow. I'm wondering am I doing something wrong. The video is 2mb if that makes any difference.
Inside the the session's completionHandler I tried updating the returned data on the main queue but there was a scrolling glitch while doing that. Using DispatchQueue.global().async there is no scrolling glitch but it seems like it takes longer return
// all of this occurs inside my data model
var cachedURL: URL?
let videoUrl = dict["videoUrl"] as? String ?? "" // eg. "https://firebasestorage.googleapis.com/v0/b/myApp.appspot.com/o/abcd%277920FHqFBkl7D6j%2F-MC65EFG_qT0KZbdtFhU%2F48127-8C29-4666-96C9-E95BE178B268.mp4?alt=media&token=bf85dcd1-8cee-428e-87bc-91800b7316de"
guard let url = URL(string: videoUrl) else { return }
useURLSessionToCacheVideo(url)
func useURLSessionToCacheVideo(_ url: URL) {
    
    let lastPathComponent = url.lastPathComponent
    let cachesDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
    let file = cachesDir.appendingPathComponent(lastPathComponent)
    
    if FileManager.default.fileExists(atPath: file.path) {
        self.cachedURL = file
        print("url already exists in cache")
        return
    }
    
    URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
        
        if let error = error { return }
        
        if let response = response as? HTTPURLResponse {
            guard response.statusCode == 200 else {
                return
            }
        }
        
        guard let data = data else {
            return
        }
        
        DispatchQueue.global().async { // main queue caused a hiccup while scrolling a cv
            do {
                try data.write(to: file, options: .atomic)
                DispatchQueue.main.async { [weak self] in
                    self?.cachedURL = file
                }
            } catch {
                print("couldn't cache video file")
            }
        }
        
    }).resume()
}