Lui*_*roa 87 firebase firebase-storage
我正在努力上传图片,一切都很棒,但我有100张图片,我想在我的所有图片中显示View
,因为我在文件夹中找到完整的图片列表,我找不到任何API工作.
Fra*_*len 90
Firebase存储中目前没有API调用来列出文件夹中的所有文件.如果需要此类功能,则应将文件的元数据(例如下载URL)存储在可以列出的位置.在火力地堡实时数据库是为这个完美的,并允许您亦可轻松与他人分享的网址.
您可以在我们的FriendlyPix示例应用程序中找到一个好的(但有些参与)样本.Web版本的相关代码在这里,但也有iOS和Android版本.
joh*_*bay 31
自2017年3月起:随着Firebase云功能的增加,以及Firebase与Google Cloud的更深层次集成,现在可以实现.
借助云功能,您可以使用Google Cloud Node程序包在云存储上执行史诗般的操作.以下示例将所有文件URL从云存储中转换为阵列.每次将某些内容保存到谷歌云存储时,都会触发此功能.
注1:这是一个计算相当昂贵的操作,因为它必须遍历存储桶/文件夹中的所有文件.
注2:我写这个只是作为一个例子,没有在承诺等方面付出太多细节.只是为了提出一个想法.
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
// let's trigger this function with a 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
// this is just for the sake of this example. Ideally you should get the path from the object that is uploaded :)
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(signedUrlConfig, function(err, fileURL) {
console.log(fileURL);
fileURLs.push(fileURL);
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
我希望这会给你一般的想法.有关更好的云功能示例,请查看Google的Github repo,其中包含Firebase的Cloud Functions示例.另请查看他们的Google Cloud Node API文档
Ros*_*des 22
截至2019年5月,适用于Cloud Storage的Firebase SDK 版本6.1.0现在支持列出存储桶中的所有对象。您只需拨打listAll()
一个Reference
:
// Since you mentioned your images are in a folder,
// we'll create a Reference to that folder:
var storageRef = firebase.storage().ref("your_folder");
// Now we get the references of these images
storageRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
// And finally display them
displayImage(imageRef);
});
}).catch(function(error) {
// Handle any errors
});
function displayImage(imageRef) {
imageRef.getDownloadURL().then(function(url) {
// TODO: Display the image on the UI
}).catch(function(error) {
// Handle any errors
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,要使用此功能,您必须选择加入“安全规则”的第2版,这可以通过制作rules_version = '2';
安全规则的第一行来完成:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
Run Code Online (Sandbox Code Playgroud)
我建议检查文档以获取更多参考。
同样,根据setup,在步骤5上,此脚本不允许使用,Node.js
因为它require("firebase/app");
不会firebase.storage()
作为函数返回。这只能通过使用来实现import * as firebase from 'firebase/app';
。
Mik*_*ald 18
由于没有列出任何语言,我将在Swift中回答这个问题.我们强烈建议您同时使用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]()
Run Code Online (Sandbox Code Playgroud)
上传:
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)
}
Run Code Online (Sandbox Code Playgroud)
下载:
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)
})
})
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅零到应用程序:使用Firebase进行开发,以及它的相关源代码,以获取有关如何执行此操作的实际示例.
Ber*_*rci 10
结合这篇文章和这里的一些答案,经过一些个人研究,对于带有打字稿的 NodeJS,我设法通过使用以下方法来完成此任务firebase-admin
:
import * as admin from 'firebase-admin';
const getFileNames = () => {
admin.storage().bucket().getFiles(autoPaginate: false).then(([files]: any) => {
const fileNames = files.map((file: any) => file.name);
return fileNames;
})
}
Run Code Online (Sandbox Code Playgroud)
就我而言,我还需要从 firebase 存储中获取特定文件夹内的所有文件。根据谷歌存储,这些文件夹不存在,而是一种命名约定。{ prefix: ${folderName}, autoPaginate: false }
无论如何,我通过在函数调用中添加以下内容来设法做到这一点(无需将每个文件的完整路径保存到数据库中)getFiles
:
...
const getFileNames = (folderName: string) => {
admin.storage().bucket().getFiles({ prefix: `${folderName}`, autoPaginate: false })
.then(([files]: any) => {
...
Run Code Online (Sandbox Code Playgroud)
小智 5
一种解决方法是创建一个内部没有任何内容的文件(即 list.txt),在此文件中,您可以使用所有文件 URL 的列表设置自定义元数据(即 Map<String, String>)。
因此,如果您需要下载 fodler 中的所有文件,您首先下载 list.txt 文件的元数据,然后遍历自定义数据并下载带有 Map 中 URL 的所有文件。
小智 5
我在做我的项目时也遇到了这个问题。我真的希望他们提供一个结束 api 方法。无论如何,我就是这样做的:当您将图像上传到 Firebase 存储时,创建一个对象并将该对象同时传递到 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);
}
});
Run Code Online (Sandbox Code Playgroud)
稍后当您想要从文件夹下载图像时,您只需遍历该文件夹下的文件。此文件夹与 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) {
}
});
Run Code Online (Sandbox Code Playgroud)
现在我有一个包含每个图像的 URI 的对象列表,我可以对它们做任何我想做的事情。为了将它们加载到 imageView 中,我创建了另一个线程。
@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;
}
Run Code Online (Sandbox Code Playgroud)
这将返回一个位图列表,当它完成时,我只需将它们附加到主活动中的 ImageView。下面的方法是@Override,因为我创建了接口并在其他线程中监听完成。
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我必须先等待返回列表图像,然后再调用线程来处理列表位图。在这种情况下,图像包含 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);
}
Run Code Online (Sandbox Code Playgroud)
希望有人觉得它有帮助。它也将成为我未来的行会路线。
使用 Cloud Function 将图像添加到数据库的另一种方法来跟踪每个上传的图像并将其存储在数据库中。
exports.fileUploaded = functions.storage.object().onChange(event => {
const object = event.data; // the object that was just uploaded
const contentType = event.data.contentType; // This is the image Mimme type\
// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
console.log('This is not an image.');
return null;
}
// Get the Signed URLs for the thumbnail and original image.
const config = {
action: 'read',
expires: '03-01-2500'
};
const bucket = gcs.bucket(event.data.bucket);
const filePath = event.data.name;
const file = bucket.file(filePath);
file.getSignedUrl(config, function(err, fileURL) {
console.log(fileURL);
admin.database().ref('images').push({
src: fileURL
});
});
});
Run Code Online (Sandbox Code Playgroud)
完整代码在这里:https : //gist.github.com/bossly/fb03686f2cb1699c2717a0359880cf84
对于节点js,我使用了这段代码
const Storage = require('@google-cloud/storage');
const storage = new Storage({projectId: 'PROJECT_ID', keyFilename: 'D:\\keyFileName.json'});
const bucket = storage.bucket('project.appspot.com'); //gs://project.appspot.com
bucket.getFiles().then(results => {
const files = results[0];
console.log('Total files:', files.length);
files.forEach(file => {
file.download({destination: `D:\\${file}`}).catch(error => console.log('Error: ', error))
});
}).catch(err => {
console.error('ERROR:', err);
});
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以通过 listAll() 方法列出 firebase 存储目录中的文件。要使用此方法,必须实现此版本的 firebase 存储。'com.google.firebase:firebase-storage:18.1.1'
https://firebase.google.com/docs/storage/android/list-files
请记住,将安全规则升级到版本 2。
归档时间: |
|
查看次数: |
77907 次 |
最近记录: |