2017-07-20 3 views
2

Ich gebe meine ersten Schritte mit Firebase Storage Web und gestehe, dass Javascript nicht meine Spezialität ist.Laden Sie mehrere Bilder von Firebase Storage herunter

Ich habe eine Webseite (PHP) mit einer Liste von Personennamen und ich möchte ihr jeweiliges Foto neben dem Namen zeigen. Die Bilder werden in einem Firebase-Speicherordner gespeichert.

Hier ist ein einfaches Beispiel für die HTML (mit PHP generiert):

<div id="people_list"> 
    <div class="list_row"> 
     <div class="photo"> 
      <img id="photo1" src="images/stdphoto.png" width="50" height="50"> 
     </div> 
     <div class="name"> 
      People Name 1 
     </div> 
    </div> 
    <div class="list_row"> 
     <div class="photo"> 
      <img id="photo2" src="images/stdphoto.png" width="50" height="50"> 
     </div> 
     <div class="name"> 
      People Name 2 
     </div> 
    </div> 
</div> 

Ich habe bereits die Firebase API gemäß den Anweisungen in dieser Seite https://firebase.google.com/docs/web/setup und initialisieren es wie folgt aus:

firebase.initializeApp(config); 
firebase.auth().signInAnonymously(); // Ignoring security for now 

Und hier ist mein Code, um ein Foto zu laden. Es funktioniert perfekt!

var storage = firebase.storage(); 
var refPath = storage.ref('photos/johnnydepp.jpg'); 
refPath.getDownloadURL().then(function(url) { 
    document.getElementById('photo1').src = url; 
}).catch(function(error) { 
    console.log(error); 
}); 

Aber jetzt versuche ich, alle Bilder in der Seite zu laden, so dass ich erstellt ein Javascript-Array-Variable mit den Dateinamen (mit PHP geladen) ein tat wie folgt aus:

var photos = ["johnnydepp", "jimcarrey", "emmawatson"]; 

var photoId = 0; 
var refPath = null; 
var storage = firebase.storage(); 
for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    refPath = storage.ref('photos/' + photos[i] + '.jpg'); 
    refPath.getDownloadURL().then(function(url) { 
     document.getElementById('photo' + photoId).src = url; 
    }).catch(function(error) { 
     console.log(error); 
    }); 
} 

I Ich weiß nicht warum, aber nur das letzte Foto in der Liste wird geladen. In der Javascript-Konsole sind keine Fehler aufgetreten.

Bitte, weißt du, was ich falsch mache? Vielen Dank!

EDIT (meine Lösung):

const promises = []; 

photos.forEach(val => { 
      const promise = firebase.storage() 
        .ref('photos/' + val + '.jpg') 
        .getDownloadURL() 
        .catch(err => { 
      console.log('error', err); 
           return ""; 
        }) 
        .then(fileUrl => { 
           return fileUrl; 
        }); 
   promises.push(promise); 
}); 

Promise.all(promises) 
   .catch(err => { 
     console.log('error', err); 
   }) 
   .then(urls => { 
     for (var i = 0; i <= urls.length - 1; i++) { 
      if (urls[i] != '') { 
       document.getElementById('photo' + (i + 1)).src = urls[i]; 
      } 
     } 
}); 

Antwort

1

Das Problem hierbei ist, dass Sie eine Asynchron-Funktion in einer Schleife verwenden, können Sie eine selbst Umwicklungsfunktion auf diese Weise verwendet werden sollen:

for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    refPath = storage.ref('photos/' + photos[i] + '.jpg'); 
    (function(pid) { 
     refPath.getDownloadURL().then(function(url) { 
      document.getElementById('photo' + pid).src = url; 
     }).catch(function(error) { 
      console.log(error); 
     }); 
    })(photoId); 
} 

Ihr Code funktioniert nicht, weil Sie den Empfang Wert von Firebase nach einer Verzögerung, wenn Sie getElemById(photoId), photoId aufrufen, ist der Wert bereits geändert. Sie können das gleiche Verhalten siehe hier:

for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    setTimeout(function() { 
     console.log(photoId); 
    }, 1000) 
} 

Selbst Umwicklungsfunktion eine closure erzeugt, die Ihren photoId Wert

+1

Danke Devid! Deine Erklärung war sehr gut, ich habe verstanden, was ich falsch gemacht habe. Ich werde deine Antwort akzeptieren, aber auch meine Lösung in der Frage lassen. – Guybrush

0

Das Abrufen Download-URL sind Asynchron-Anfragen (Versprechen) und den nächsten Schleifenzyklus ausführen, ohne die vorherigen zu lassen letzte zu beenden und somit nur ausgeführt wird, vollständig.

Ich schlage vor, Sie nehmen einen anderen Ansatz.

var photos = ["johnnydepp", "jimcarrey", "emmawatson"]; 

var photoId = 0; 
var storage = firebase.storage(); 
var promises = []; 
for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    promises.push(storage.ref('photos/' + photos[i] + '.jpg').getDownloadURL()); 
} 

photoId = 0; 
Promise.all(promises, data => { 
    for (var i = 0; i <= photos.length - 1; i++) { 
     photoId = i + 1; 
     document.getElementById('photo' + photoId).src = data[i]; 
    } 
}); 
+0

Danke Anand hält, aber sind Sie sicher, dass diese Arbeit? Ich kann es nicht schaffen zu arbeiten, auch wenn Sie die Schleifen entfernen und statische Werte verwenden ... – Guybrush

+0

Oh, und es gibt keine Fehlermeldungen im Konsolenprotokoll ... – Guybrush

Verwandte Themen