Загрузите файлы в Firebase Storage, используя Node.js
Я пытаюсь понять, как загружать файлы в Firebase Storage, используя Node.js. Моей первой попыткой было использовать библиотеку Firebase:
"use strict";
var firebase = require('firebase');
var config = {
apiKey: "AIz...kBY",
authDomain: "em....firebaseapp.com",
databaseURL: "https://em....firebaseio.com",
storageBucket: "em....appspot.com",
messagingSenderId: "95...6"
};
firebase.initializeApp(config);
// Error: firebase.storage is undefined, so not a function
var storageRef = firebase.storage().ref();
var uploadTask = storageRef.child('images/octofez.png').put(file);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed', function(snapshot){
...
}, function(error) {
console.error("Something nasty happened", error);
}, function() {
var downloadURL = uploadTask.snapshot.downloadURL;
console.log("Done. Enjoy.", downloadURL);
});
Но оказывается, что Firebase не может загружать файлы со стороны сервера, как это четко указано в документации:
Firebase Storage не входит в состав серверной части Firebase npm. Вместо этого вы можете использовать клиент gcloud Node.js.
$ npm install --save gcloud
В своем коде вы можете получить доступ к своему хранилищу, используя:
var gcloud = require('gcloud')({ ... }); var gcs = gcloud.storage(); var bucket = gcs.bucket('<your-firebase-storage-bucket>');
Можем ли мы использовать
gcloud
без учетной записи в Google Cloud Platform? Как?Если нет, то почему загрузка файлов в Firebase Storage со стороны клиента возможна?
Разве мы не можем просто создать библиотеку, которая делает такие же запросы со стороны сервера?
Как Firebase Storage связан с Google Cloud Platform вообще? Почему Firebase позволяет загружать изображения только со стороны клиента?
Моя вторая попытка состояла в том, чтобы использовать gcloud
библиотека, как указано в документации:
var gcloud = require("gcloud");
// The following environment variables are set by app.yaml when running on GAE,
// but will need to be manually set when running locally.
// The storage client is used to communicate with Google Cloud Storage
var storage = gcloud.storage({
projectId: "em...",
keyFilename: 'auth.json'
});
storage.createBucket('octocats', function(err, bucket) {
// Error: 403, accountDisabled
// The account for the specified project has been disabled.
// Create a new blob in the bucket and upload the file data.
var blob = bucket.file("octofez.png");
var blobStream = blob.createWriteStream();
blobStream.on('error', function (err) {
console.error(err);
});
blobStream.on('finish', function () {
var publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
console.log(publicUrl);
});
fs.createReadStream("octofez.png").pipe(blobStream);
});
7 ответов
При использовании библиотеки firebase на сервере вы, как правило, авторизуетесь, используя служебную учетную запись, поскольку это даст вам, например, административный доступ к базе данных реального времени. Вы можете использовать тот же файл учетных данных учетной записи службы для авторизации gcloud.
Кстати, проект Firebase, по сути, также является проектом Google Cloud Platform, вы можете получить доступ к своему проекту Firebase как на https://console.firebase.google.com/ и на https://console.cloud.google.com/ и https://console.developers.google.com/ Вы можете увидеть свой идентификатор проекта в консоли Firebase> Настройки проекта или в панели управления облачной консоли
При использовании gcloud SDK убедитесь, что вы используете (уже существующее) то же самое хранилище, которое использует Firebase Storage. Вы можете найти название корзины в сети Firebase. config
объект или на вкладке Firebase Storage. В основном ваш код должен начинаться так:
var gcloud = require('gcloud');
var storage = gcloud.storage({
projectId: '<projectID>',
keyFilename: 'service-account-credentials.json'
});
var bucket = storage.bucket('<projectID>.appspot.com');
...
Firebase Storage теперь поддерживается административным SDK с NodeJS:
https://firebase.google.com/docs/reference/admin/node/admin.storage
// Get the Storage service for the default app
var defaultStorage = firebaseAdmin.storage();
var bucket = defaultStorage.bucket('bucketName');
...
Firebase Admin SDK позволяет получить прямой доступ к облачному хранилищу Google.
Для получения более подробной информации посетите Введение в Admin Cloud Storage API.
var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: "<BUCKET_NAME>.appspot.com"
});
var bucket = admin.storage().bucket();
bucket.upload('Local file to upload, e.g. ./local/path/to/file.txt')
Я надеюсь, что это будет полезно для вас. Я загрузил один файл локально, а затем добавил токен доступа, используя UUID, после этого я загрузил его в хранилище Firebase. Там, после того, как я генерирую URL-адрес загрузки. Если мы нажмем на этот URL, он автоматически загрузит файл.
const keyFilename="./xxxxx.json"; //replace this with api key file
const projectId = "xxxx" //replace with your project id
const bucketName = "xx.xx.appspot.com"; //Add your bucket name
var mime=require('mime-types');
const uuidv1 = require('uuid/v1');//this for unique id generation
//const mime = require('mime');
const gcs = require('@google-cloud/storage')({
projectId,
keyFilename
});
const bucket = gcs.bucket(bucketName);
const filePath = "./sample.odp";
const remotePath = "/XXXX";
const fileMime = mime.lookup(filePath);
//we need to pass those parameters for this function
var upload = (filePath, remoteFile, fileMime) => {
let uuid = uuidv1();
return bucket.upload(filePath, {
destination: remoteFile,
uploadType: "media",
metadata: {
contentType: fileMime,
metadata: {
firebaseStorageDownloadTokens: uuid
}
}
})
.then((data) => {
let file = data[0];
return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
});
}
//This function is for generation download url
upload(filePath, remotePath, fileMime).then( downloadURL => {
console.log(downloadURL);
});
Обратите внимание, что gcloud устарела, вместо этого используйте google-cloud. SERVICE_ACCOUNT_KEY_FILE_PATH можно найти в настройках проекта -> Учетные записи служб.
var storage = require('@google-cloud/storage');
var gcs = storage({
projectId: PROJECT_ID,
keyFilename: SERVICE_ACCOUNT_KEY_FILE_PATH
});
// Reference an existing bucket.
var bucket = gcs.bucket(PROJECT_ID + '.appspot.com');
...
Или вы могли бы просто заполнить XmlHttpRequest
вот так -
const XMLHttpRequest = require("xhr2");
global.XMLHttpRequest = XMLHttpRequest
и импорт
require('firebase/storage');
Вот и все. Все firebase.storage()
методы должны теперь работать.
Я реализовал API для загрузки файла в хранилище Firebase:
const fs = require('firebase-admin');
const app = require('express')();
const serviceAccount = require('./serviceAccountKey_DEV.json');
fs.initializeApp({
credential: fs.credential.cert(serviceAccount),
storageBucket: `${serviceAccount.project_id}.appspot.com`
});
// Upload the file on firebase storage
app.get("/upload-on-firebase", async (req, res, next) => {
var bucket = fs.storage().bucket();
const result = await bucket.upload('data.json');
console.log('result :', result);
return res.send(result);
});
Вызовите API для загрузки:
curl --location --request GET 'http://localhost:3000/upload-on-firebase'
Ответ:
[
{
"_events": {},
"_eventsCount": 0,
"metadata": {
"kind": "storage#object",
"id": "project_id.appspot.com/data.json/1678222222",
"selfLink": "https://www.googleapis.com/storage/v1/b/project_id.appspot.com/o/data.json",
"mediaLink": "https://storage.googleapis.com/download/storage/v1/b/project_id.appspot.com/o/data.json",
"name": "data.json",
"bucket": "project_id.appspot.com",
"generation": "16787922222222",
"metageneration": "1",
"contentType": "application/json",
"storageClass": "STANDARD",
....
....
....
},
"baseUrl": "/o",
}
]