应用在后台运行一段时间后,Firebase 存储下载任务未完成
Posted
技术标签:
【中文标题】应用在后台运行一段时间后,Firebase 存储下载任务未完成【英文标题】:Firebase Storage download task is not completing after the app has spent some time in the background 【发布时间】:2016-11-04 06:25:19 【问题描述】:我正在从 Firebase 存储中下载图像,如下所示:
let storage = FIRStorage.storage()
// Create a storage reference from our storage service
let storageRef = storage.reference(forURL: "MY_STORAGE_URL")
let imageRef = storageRef.child("Path_to_image")
// Download image in memory
let downloadTask = imageRef.data(withMaxSize: 1 * 1024 * 1024)
(data, error) -> Void in
if (error != nil)
//Handle the error
else
guard let imageData = data else
print("Unable to unwrap image data.")
return
let downloadedImage = UIImage(data: imageData)
//Do some stuff with the image
我还使用以下观察者监视下载发生的情况:
// Observe changes in status
downloadTask.observe(.resume) (snapshot) -> Void in
// Download resumed, also fires when the download starts
downloadTask.observe(.pause) (snapshot) -> Void in
// Download paused
downloadTask.observe(.progress) (snapshot) -> Void in
// Download reported progress
downloadTask.observe(.success) (snapshot) -> Void in
// Download completed successfully
downloadTask.observe(.failure) (snapshot) -> Void in
//Download failed
这一切在应用程序首次启动时运行良好。但是,如果应用程序进入后台并且我使用其他一些应用程序(Facebook、Twitter 等),然后将应用程序带回前台,我会遇到问题。如果我让应用程序打开并在前台运行超过或等于 1 小时,我也会遇到问题。
问题是let downloadTask = imageRef.data(withMaxSize:
blah blah blah(在上面的第一块代码中)中的完成处理程序永远不会被调用。如果从不调用完成处理程序,我将永远无法解包数据并尝试在我的应用程序中使用图像。
此外,在downloadTask
观察者中,唯一被触发的完成处理程序是.resume
和.progress
。 .success
或 .failure
事件永远不会被触发。这对我来说似乎是一个 Firebase 存储错误,但我不确定。有没有其他人遇到过类似的问题?我不明白为什么代码在新启动时就可以正常工作,但是在前台一段时间后或在后台一段时间后,图像下载停止工作。提前感谢您提供的任何意见。
【问题讨论】:
我没有看到enque()
方法被触发。
我的示例几乎直接来自文档。他们不在那里调用enqueue()
方法。你能解释一下为什么这是必要的吗?
如果你想在ios中后台运行,你不需要做一些特殊的事情吗? developer.apple.com/library/content/documentation/iPhone/…
【参考方案1】:
不幸的是,这是目前的预期行为。 Firebase Storage(目前)仅前台:如果应用程序是后台的,我们没有持久化上传URL,并且无法在后台上传,也无法在退出后台后重新启动它,因此它可能被杀死操作系统和项目未上传。
这是我们想要解决的 The Next Big Thing™(our android SDK makes it possible,虽然不容易),但不幸的是,目前我们还没有在这方面取得更多进展。
附带说明一下,活动更改后您的观察者将不存在--downloadTask
一旦应用程序后台运行就消失了,所以当它回到前台时,我们基本上需要一个方法来检索当前后台的所有任务,并允许您备份观察者。比如:
FIRStorage.storage().backgroundedTasks (tasks) -> Void in
// tasks is an array of upload and download tasks
// not sure if it needs to be async
【讨论】:
感谢迈克的回答。为了清楚起见并确保我们相互理解,我并不想在下载大图像的过程中为应用程序设置背景。我只希望这些方法在应用程序处于前台时被调用时能够正常工作。这真的是预期的行为吗?注销并重新登录并不能解决问题。我必须完全重新启动应用程序才能再次开始下载图像。这对我的用户来说非常令人沮丧。有什么解决办法吗? 我一定没有完全理解你的问题,抱歉。更清楚地说,听起来所有的观察者和完成块在前台工作正常,但问题只是在前台很长时间后才开始出现,或者如果应用程序是后台的,然后出现在前台.您是否碰巧有一个示例应用程序并为此进行了复制,以便我们可以在本地对其进行调试?我似乎无法可靠地做到这一点。 不用担心。不幸的是,我没有该应用程序的公共回购。我发现重新创建错误的最简单方法是: 1. 在 Xcode 模拟器中启动应用程序。验证其按预期工作。 2. 等待一小时。一小时内不要触摸应用程序中的任何东西。 3. 尝试下载一些图像。图像不会加载。我知道这很耗时,但这是我发现的唯一可靠的方法来重新创建错误。 @MikeMcDonald 使用 iOS 版 Firebase 存储在后台上传还有什么进展吗?或者至少像 Android 这样的 sessionUri,这样我就可以在 backgroundTask 被杀死后恢复上传。如果不可能,我将不得不使用另一个使用 URLSession 的解决方案,它允许在上传继续时暂停或终止应用程序。以上是关于应用在后台运行一段时间后,Firebase 存储下载任务未完成的主要内容,如果未能解决你的问题,请参考以下文章
在我的颤振(android)应用程序中 - Firebase 推送通知在一段时间后停止接收每个用户
利用 Firebase 和 Google App Engine 将后台逻辑添加到实时数据