[英]Can't upload to google cloud or firebase storage bucket from nodejs
I have been trying to upload some images to my firebase storage bucket . 我一直试图将一些图像上传到我的Firebase存储桶中。 I have followed this official docs :-
我已经关注了这个官方文档:
https://firebase.google.com/docs/storage/admin/start https://firebase.google.com/docs/storage/admin/start
and https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/latest/storage/bucket 和https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/latest/storage/bucket
I am able to see the files which are already present in the bucket (these files were stored there using an android app) 我能够看到存储桶中已经存在的文件(这些文件使用Android应用程序存储在此处)
But I'm not able to upload local files from nodejs's admin.storage module . 但是我无法从nodejs的admin.storage模块上传本地文件。
Here is the code : 这是代码:
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://myprojectid.firebaseio.com/" ,
storageBucket : "myprojectid.appspot.com/"
});
bucket = admin.storage().bucket() ;
bucket.upload('./mylocalfile.jpg' , (err , file , response)=>{
console.log(err) ; //always gives me err
console.log(file) ; //gives undefined
}) ;
But bucket.getFiles().then(objects=>console.log(objects)) ;
但是
bucket.getFiles().then(objects=>console.log(objects)) ;
works perfectly and prints the files present in the root . 可以完美工作并打印根目录中存在的文件。
How to fix this ? 如何解决呢?
Here is the error
it prints when console logging err
: 下面是
error
它打印在控制台日志err
:
{ ApiError: Not Found
at Object.parseHttpRespMessage (C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\@google-cloud\common\src\util.js:156:33)
at Object.handleResp (C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\@google-cloud\common\src\util.js:131:18)
at C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\@google-cloud\common\src\util.js:465:12
at Request.onResponse [as _callback] (C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\retry-request\index.js:179:7)
at Request.self.callback (C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\request\request.js:186:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (C:\Users\Natesh\Desktop\AttentionPlease_backend\functions\node_modules\firebase-admin\node_modules\request\request.js:1163:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
code: 404,
errors: [],
response:
IncomingMessage {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: true,
endEmitted: true,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events:
{ end: [Object],
close: [Object],
data: [Function],
error: [Function] },
_eventsCount: 4,
_maxListeners: undefined,
socket:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: false,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 9,
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: 'www.googleapis.com',
_readableState: [Object],
readable: true,
domain: [Object],
_maxListeners: undefined,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
destroyed: false,
_bytesDispatched: 4047,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [Object],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: null,
read: [Function],
_consuming: true,
_idleTimeout: -1,
_idleNext: null,
_idlePrev: null,
_idleStart: 1307656 },
connection:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: false,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 9,
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: 'www.googleapis.com',
_readableState: [Object],
readable: true,
domain: [Object],
_maxListeners: undefined,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
destroyed: false,
_bytesDispatched: 4047,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [Object],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: null,
read: [Function],
_consuming: true,
_idleTimeout: -1,
_idleNext: null,
_idlePrev: null,
_idleStart: 1307656 },
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers:
{ 'x-guploader-uploadid': 'AEnB2UqADzuHb4O7UjdBAui1cDWeLNO4s0YuT2krCPoYIHaUrYPjXRH8rBU0mcSi9n7sie11PhALTN2vOKkhykW0apqTbrNB9Q',
vary: 'Origin, X-Origin',
'content-type': 'text/html; charset=UTF-8',
'content-length': '9',
date: 'Sat, 17 Mar 2018 13:24:19 GMT',
server: 'UploadServer',
'alt-svc': 'hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="41,39,35"' },
rawHeaders:
[ 'X-GUploader-UploadID',
'AEnB2UqADzuHb4O7UjdBAui1cDWeLNO4s0YuT2krCPoYIHaUrYPjXRH8rBU0mcSi9n7sie11PhALTN2vOKkhykW0apqTbrNB9Q',
'Vary',
'Origin',
'Vary',
'X-Origin',
'Content-Type',
'text/html; charset=UTF-8',
'Content-Length',
'9',
'Date',
'Sat, 17 Mar 2018 13:24:19 GMT',
'Server',
'UploadServer',
'Alt-Svc',
'hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="41,39,35"' ],
trailers: {},
rawTrailers: [],
upgrade: false,
url: '',
method: null,
statusCode: 404,
statusMessage: 'Not Found',
client:
TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: false,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object],
_eventsCount: 9,
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: 'www.googleapis.com',
_readableState: [Object],
readable: true,
domain: [Object],
_maxListeners: undefined,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
destroyed: false,
_bytesDispatched: 4047,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [Object],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: null,
read: [Function],
_consuming: true,
_idleTimeout: -1,
_idleNext: null,
_idlePrev: null,
_idleStart: 1307656 },
_consuming: true,
_dumped: false,
req:
ClientRequest {
domain: [Object],
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: false,
upgrading: false,
chunkedEncoding: true,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedHeader: [Object],
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'POST /upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile HTTP/1.1\r\nUser-Agent: gcloud-node-storage/1.4.0\r\nx-goog-api-client: gl-node/6.11.5 gccl/1.4.0\r\nAuthorization: Bearer ya29.c.<PLACEHOLDER_FOR_SOME_LONG_AUTH_ID>\r\nhost: www.googleapis.com\r\naccept-encoding: gzip, deflate\r\ntransfer-encoding: chunked\r\ncontent-type: multipart/related; boundary=6e012a90-2cb1-4c46-9de5-bb75cb5949ea\r\nConnection: keep-alive\r\n\r\n',
_headers: [Object],
_headerNames: [Object],
_onPendingData: null,
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
_ended: true,
parser: null,
timeoutCb: null,
res: [Circular] },
request:
Request {
domain: [Object],
_events: [Object],
_eventsCount: 5,
_maxListeners: undefined,
timeout: 60000,
gzip: true,
forever: true,
pool: [Object],
method: 'POST',
uri: [Object],
headers: [Object],
callback: [Function],
readable: true,
writable: true,
explicitMethod: true,
_qs: [Object],
_auth: [Object],
_oauth: [Object],
_multipart: [Object],
_redirect: [Object],
_tunnel: [Object],
setHeader: [Function],
hasHeader: [Function],
getHeader: [Function],
removeHeader: [Function],
localAddress: undefined,
dests: [],
__isRequestRequest: true,
_callback: [Function: onResponse],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'www.googleapis.com',
url: [Object],
path: '/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
httpModule: [Object],
agentClass: [Object],
agentOptions: [Object],
agent: [Object],
src: [Object],
_started: true,
href: 'https://www.googleapis.com/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
req: [Object],
ntick: true,
response: [Circular],
originalHost: 'www.googleapis.com',
originalHostHeaderName: 'host',
responseContent: [Circular],
_destdata: true,
_ended: true,
_callbackCalled: true },
toJSON: [Function: responseToJSON],
caseless: Caseless { dict: [Object] },
read: [Function],
body: 'Not Found' },
message: 'Not Found' }
Unfortunately the 'upload' function only receive path to local file or url, so it cause some complexity when implement uploading file REST api by cloud functions. 不幸的是,“上传”功能仅接收本地文件或url的路径,因此在通过云功能实现上传文件REST api时会引起一些复杂性。 I'm guessing it shouldn't be a proper way to upload a file to cloud function server and upload a local file to cloud storage.
我猜这不是将文件上传到云功能服务器并将本地文件上传到云存储的正确方法。
Here's what I accomplished to make upload endpoint to firebase (gcloud) storage using multer to get file from the request, then convert it to data and use save function to upload. 这是我使用multer从请求中获取文件,然后将其转换为数据并使用保存功能进行上传的方法,以将上传终结点存储到Firebase(gcloud)存储中。
const functions = require('firebase-functions'); const admin = require('firebase-admin'); const express = require('express'); const multer = require('multer'); const app = express(); const fileUpload = multer(); admin.initializeApp(.......); /* * Upload File **/ app.post('/', fileUpload.single('file'), functions.https.onRequest((req, res) => { const file = req.file; const bucket = admin.storage().bucket(); const name = file.originalname; const bucketFile = bucket.file(name); bucketFile .save(new Buffer(file.buffer)) .then(() => { res.status(200).json({ status: 'success', data: Object.assign({}, bucketFile.metadata, { downloadURL: `https://storage.googleapis.com/${bucket.name}/${name}`, }) }); }) .catch(err => { res.status(500).json({ status: 'error', errors: err, }); }); }));
Here's my POSTMAN screen for test. 这是我的POSTMAN屏幕进行测试。
Let me know if you need further help. 让我知道您是否需要进一步的帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.