You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift上传文件至Firebase Storage后下载保存异常问题

问题描述
  • 我用Swift开发了一个功能:将本地设备的文件以原始二进制格式上传至Firebase Storage,上传完成后在Firebase存储中能看到文件,且文件大小显示正确。
  • 现在通过文件的Firebase Storage下载URL尝试将文件下载到本地设备,期望文件能出现在iOS「Files」应用的下载目录中。点击下载按钮后没有报错,但文件并未出现在「Files」里;不过把该URL粘贴到谷歌浏览器中,文件可以自动下载。
  • 之后我在「Files」中找到了下载的文件,但点击打开后仅显示文档ID和字节大小,在Mac上查看该文件也无法看到真实的文本内容。我知道下载逻辑存在问题,但不确定上传环节是否也有问题?

原始代码

import SwiftUI
import UniformTypeIdentifiers
import Firebase
import FirebaseStorage

struct FilePicker: View {
   @State private var showPicker = false
   // 示例中使用的是Firebase Storage中存储的PDF文档URL
   @State private var finalURL: String? = "https://firebasestorage.googleapis.com:443/v0/b/hustle-85b6c.appspot.com/o/files%2FF425B036-D3DC-4B8A-9CE0-D7A8893D5466?alt=media&token=5a33534d-ea81-45c2-8113-042a9d021d05"
   
   var body: some View {
       VStack {
           Spacer()
           if let url = finalURL {
               Button(action: {
                   downloadFile(urlS: url)
               }, label: {
                   Text("download")
               })
           }
           
           Button(action: {
               showPicker.toggle()
           }, label: {
               Image(systemName: "paperclip")
                   .padding()
                   .foregroundStyle(.blue)
                   .background(.gray)
                   .clipShape(Circle())
           })
           Spacer()
       }
       .fileImporter(isPresented: $showPicker, allowedContentTypes: [UTType.data]) { result in
           do {
               let url = try result.get()
               let accessing = url.startAccessingSecurityScopedResource()
               defer {
                   if accessing {
                       url.stopAccessingSecurityScopedResource()
                   }
               }
               
               if let fileData = try? Data(contentsOf: url) {
                   uploadFile(data: fileData, location: "files") { urlS in
                       print(urlS)
                       finalURL = urlS
                   }
               }
           } catch {
               print("File picker error: \(error)")
           }
       }
   }
   func downloadFile(urlS: String) {
       guard let url = URL(string: urlS) else {
           return
       }
       let downloadTask = URLSession.shared.dataTask(with: url) { (data, response, error) in
           if let error = error {
               print("Error downloading file: \(error)")
               return
           }
           if let data = data {
               saveFile(data: data, fileName: "download\(UUID().uuidString.prefix(5))")
           }
       }
       downloadTask.resume()
   }
   func saveFile(data: Data, fileName: String) {
       guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
           return
       }
       
       let fileURL = documentsURL.appendingPathComponent(fileName)
       
       do {
           try data.write(to: fileURL)
           print("File saved")
       } catch {
           print("Error saving file: \(error)")
       }
   }
   func uploadFile(data: Data, location: String, completion: @escaping (String) -> Void) {
       let ref = Storage.storage().reference(withPath: "/\(location)/\(NSUUID().uuidString)")

       ref.putData(data, metadata: nil) { metadata, error in
           if let err = error {
               print(err)
           }
           ref.downloadURL { (url, error) in
               guard let downloadURL = url?.absoluteString else {
                   completion("")
                   return
               }
               completion(downloadURL)
           }
       }
   }
}

更新后的save函数

func saveFile(data: Data, fileName: String, fileExtension: String) {
    guard let downloadsURL = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else {
        return
    }
    let fileURL = downloadsURL.appendingPathComponent("\(fileName).\(fileExtension)")
    do {
        if !FileManager.default.fileExists(atPath: fileURL.path) {
            FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil)
        }
        try data.write(to: fileURL)
        print("File saved")
    } catch {
        print("Error saving file: \(error)")
    }
}

内容的提问来源于stack exchange,提问作者Ahmed Zaidan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:05:19