如何根据 Firebase 数据的引用从 Firebase 存储下载图像文件

How to download image file from Firebase Storage based on a reference of Firebase data

我已经为这个问题苦苦挣扎了好几天。 我正在尝试在我的网络应用程序中使用 Firebase 存储,"Upload" 部分工作正常,我喜欢它,但 "Download" 部分让我发疯。 这是我的代码:

首先我有我的 Firebase(数据)参考:

var refspaedtServ = new Firebase(FBURLSPA + $routeParams.id);
$scope.spaedServ = $firebaseObject(refspaedtServ);

我正在用一个 ID 获取我的记录。 其次我得到我的对象字段调用 "foto",是我要下载或显示的照片的名称

var lafoto = '';
refspaedtServ.on("value", function(rootSnapshot) {
  lafoto = rootSnapshot.val().foto;
  console.log("Inside image ", lafoto)
});

所以在这里我得到了照片的名称。 由于这是一个异步通信,我无法获取到值,所以我插入一个超时函数:

setTimeout(function(){ 
  console.log("outside ", lafoto);
  $scope.lafoto = lafoto 
}, 1000);

因此在 setTime 函数内部,"lafoto" 值是否正常。 然后我得到我的 Firebase 存储桶的引用:

var storageRef = firebase.storage().ref();
var starsRef = storageRef.child('fotos' + lafoto);

我的"Problem"来了,当我尝试下载图片时,"lafoto"的值没有了,可以构造url并且没有绑定到我的网页图像容器,我想在其中显示照片

starsRef.getDownloadURL().then(function(url) {
  console.log("la url ", url)  ;
  $scope.url = url;
}).catch(function(error) {
  switch (error.code) {
  case 'storage/object_not_found';
});

我已经进行了测试,将存储引用和 starsRef.getDownloadURL 留在 setTimeout(function) 中并且它有效(部分),我的 url 已正确创建,但它与我的无关网页。 如果我查看 console.log,我的 url 没问题,如果我点击它,给我看照片。

有什么建议吗?

此致,

维克多

您似乎丢失了对 $scope 的引用,这可能是由于您在控制器外部进行了异步调用(如果不查看整个代码就很难说)。

首先而不是 refspaedtServ.on() 然后是 setTimeout() 你应该使用 refspaedtServ.once() 其中 returns 一个承诺并将其余的逻辑移动到承诺中。然后你应该直接在 $scope 中设置承诺。如 this article 所示,可以在模板中使用 Promises。例如这样的事情应该有效:

myModule.controller('HelloCtrl', function($scope) {
  var refspaedtServ = new Firebase(FBURLSPA + $routeParams.id);
  $scope.spaedServ = $firebaseObject(refspaedtServ);
  $scope.url = refspaedtServ.once("value").then(function(rootSnapshot) {
    var lafoto = rootSnapshot.val().foto;
    console.log("Inside image ", lafoto)
    var starsRef = firebase.storage().ref('fotos' + lafoto);
    return starsRef.getDownloadURL().then(function(url) {
      console.log("la url ", url)  ;
      return url;
    }).catch(function(error) {
      switch (error.code) {
        case 'storage/object_not_found';
      }
    });
  });
})

现在 $scope.url 被分配了最终 returns 直接 url 的承诺(因为可以通过返回其他承诺来传递承诺)并且模板实际上支持承诺。

与您的问题无关:我建议将图像的 URL 直接保存在数据库中,而不仅仅是存储 URI。此 URL 不应更改,这样做会在您每次要显示图像时节省额外的请求。例如,如果您将此 URL 保存在 fotoUrl 属性中,您可以这样做:

myModule.controller('HelloCtrl', function($scope) {
  var refspaedtServ = new Firebase(FBURLSPA + $routeParams.id);
  $scope.spaedServ = $firebaseObject(refspaedtServ);
  $scope.url = refspaedtServ.once("value").then(function(snapshot) {
    return snapshot.val().fotoUrl;
  });
})