语种 : Swift 5
iOS: 13.2
macOS: Catalina 10.15.4
Firebase存储规则。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth!=null;
}
}
}
上传图片和保存下载URL的代码。 (这很好用,因为我可以看到上传到存储区的图片 和它们各自的下载URL存储到实时数据库)
let storageRef = Storage.storage().reference()
//Let's upload all workout pictures
let uploadPicsRef =
storageRef.child("WORKOUTDATA/USERS/"+self.UID!).child("WHITEBOARDWORKOUTS")
let uploadNumberRef = uploadPicsRef.child("\(String(describing: workoutNum))")
let workoutPicturesRef = uploadNumberRef.child("WORKOUTPICTURES")
let workoutPicURLRef = workoutRef.child("WORKOUTPICTURESURL")
var count = 0
var picNumber = 0
//workoutPictures list/array contains images selected from iPhone Gallery, using
//UIImagePickerController
for workoutPic in self.workoutPictures
{
let workoutPicData = workoutPic.jpegData(compressionQuality: 1.0)!
count = count + 1
let pictureName = "Picture\(count).jpg"
// Upload the file to the path in pictureRef
let pictureRef = workoutPicturesRef.child("\(pictureName)")
let metaData = StorageMetadata()
metaData.contentType = "image/jpg"
pictureRef.putData(workoutPicData, metadata: metaData) { (metadata, error) in
if error != nil {
print("Error while uploading image")
}
else
{
pictureRef.downloadURL { (url, err) in
picNumber = picNumber + 1
workoutPicURLRef.child("Picture\(picNumber)").setValue(url?.absoluteString)
}
}
}
}
下载图片的代码。
let myGroup = DispatchGroup()
let workoutPicUrls = snapshot.childSnapshot(forPath: "WORKOUTPICTURESURL")
for url in workoutPicUrls.children
{
myGroup.enter()
let snap = url as! DataSnapshot
let link = snap.value as? String
let storageRef = Storage.storage().reference()
let pictureRef = storageRef.root().child(link!)
DispatchQueue.main.async {
pictureRef.getData(maxSize: 1*2000000*2000000) { (data, err) in
if (err != nil) {
print(err!)
print(err!.localizedDescription)
} else {
let pic = UIImage(data: data!)
workoutPicsArray.append(pic!)
myGroup.leave()
}
}
}
}
错误:
Error Domain=FIRStorageErrorDomain Code=-13010 "Object https:firebasestorage.googleapis.comv0btrainer-8cb52.appspot. comoWORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547不存在。" UserInfo={object=https:firebasestorage.googleapis.comv0btrainer-8cb52.appspot.comoWORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1. jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547, ResponseBody={ "error": "code": 404, "message": "Not Found.Can not get object", "状态": { "code": 404, "message": "Not Found. 无法获取对象", "status": "GET_OBJECT" } }, bucket=trainer-8cb52.appspot.com, data={length = 115, bytes = 0x7b0a2020 22657272 6f72223a 207b0a20 ... ... 54220a20 207d0a7d }, data_content_type=applicationjson; charset=UTF-8, NSLocalizedDescription=......。Object https:firebasestorage.googleapis.comv0btrainer-8cb52.appspot.comoWORKOUTDATA%2FUSERS%2FF1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FFPicture1. jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547不存在。 ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=404}。
到目前为止,我已经尝试了什么。
https:/firebasestorage.googleapis.com/v0/b/trainer8cb52.appspot.com/o/WORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547
在chrome浏览器窗口中,打开预期的图片。谢谢你
是否有可能你在数据库中存储了完整的https URL,并试图通过将完整的https URL作为子节点添加到存储引用中来创建引用?
我认为你应该尝试在数据库中只存储路径和名称,或者你改变你的下载代码来使用https URL。
// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
let httpsReference = storage.reference(forURL: "https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg")
httpsReference.getData(maxSize: ...
另外,你在你的getData方法里面运行了 DispatchQueue.main.async
...getData本身有一个完成处理程序,可能需要一些时间,当你在 DispatchQueue.main.async
它将阻止你的代码,直到下载完成。只把更新UI的代码放在 DispatchQueue.main.async
. 在你的情况下,只要你对你的workoutPicsArray或UIImage做一些事情,更新你的视图。
看一下这里,看看你是否能弄清楚你到底是如何获取数据的。在每一行之后放一个print()可能会有帮助,以查看你在什么时候创建和使用什么。