programing

Firebase용 Cloud Functions로 업로드된 파일에서 다운로드 URL 가져오기

closeapi 2023. 7. 30. 17:48
반응형

Firebase용 Cloud Functions로 업로드된 파일에서 다운로드 URL 가져오기

Firebase용 Functions가 있는 Firebase Storage에 파일을 업로드한 후 파일 다운로드 url을 받고 싶습니다.

나는 이것을 가지고 있습니다:

...

return bucket
    .upload(fromFilePath, {destination: toFilePath})
    .then((err, file) => {

        // Get the download url of file

    });

개체 파일에 매개 변수가 많습니다. 이름이 붙은사람도이인 도.mediaLink과 같은오류가 합니다.

익명 사용자는 storage.objects.get to objects...에 액세스할 수 없습니다.

누가 나에게 공개 다운로드 URL을 얻는 방법을 알려줄 수 있습니까?

감사해요.

getSigned를 사용하여 서명된 URL을 생성해야 합니다.@google-cloud/storage NPM 모듈을 통한 URL.

예:

const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
// ...
const bucket = gcs.bucket(bucket);
const file = bucket.file(fileName);
return file.getSignedUrl({
  action: 'read',
  expires: '03-09-2491'
}).then(signedUrls => {
  // signedUrls[0] contains the file's public URL
});

@google-cloud/storage서비스 계정 자격 증명을 응용 프로그램 기본 자격 증명으로 사용하면 충분하지 않습니다.

업데이트: 이제 @google-cloud/storage에서 래퍼 역할을 하는 Firebase Admin SDK를 통해 Cloud Storage SDK에 액세스할 수 있습니다.유일한 방법은 다음 중 하나입니다.

  1. 일반적으로 기본값이 아닌 두 번째 인스턴스를 통해 특수 서비스 계정으로 SDK를 시작합니다.
  2. 또는 서비스 계정이 없는 경우 기본 App Engine 서비스 계정에 "signBlob" 권한을 부여합니다.

이 답변에는 Google/Firebase Cloud Storage에 파일을 업로드할 때 다운로드 URL을 가져오는 옵션이 요약되어 있습니다.다운로드 URL에는 세 가지 유형이 있습니다.

  1. 토큰 다운로드 URL(영구적이고 보안 기능이 있음)
  2. 서명된 다운로드 URL은 임시이며 보안 기능이 있습니다.
  3. 영구적이고 보안이 부족한 공용 다운로드 URL

토큰 다운로드 URL을 가져오는 방법은 두 가지가 있습니다. 서명된 다운로드 URL과 공개 다운로드 URL은 각각 한 가지 방법만 있습니다.

토큰 URL 방법 #1: Firebase 스토리지 콘솔에서

다운로드 URL은 Firebase 스토리지 콘솔에서 확인할 수 있습니다.

enter image description here

다운로드 URL은 다음과 같습니다.

https://firebasestorage.googleapis.com/v0/b/languagetwo-cd94d.appspot.com/o/Audio%2FEnglish%2FUnited_States-OED-0%2Fabout.mp3?alt=media&token=489c48b3-23fb-4270-bd85-0a328d2808e5

첫 번째 부분은 파일에 대한 표준 경로입니다.마지막에 토큰이 있습니다.이 다운로드 URL은 영구적입니다. 즉, 만료되지 않지만 해지할 수 있습니다.

토큰 URL 방법 #2: 프런트 엔드에서

설명서는 다음을 사용하도록 지시합니다.getDownloadURL():

let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();

이렇게 하면 Firebase 스토리지 콘솔에서 얻을 수 있는 것과 동일한 다운로드 URL을 얻을 수 있습니다.이 방법은 쉽지만 내 앱에서 어려운 당신의 파일 경로를 알아야 합니다.프런트 엔드에서 파일을 업로드할 수 있지만 이 경우 앱을 다운로드하는 모든 사용자에게 자격 증명이 노출됩니다.따라서 대부분의 프로젝트에서 Cloud Functions에서 파일을 업로드한 다음 다운로드 URL을 가져와 파일에 대한 다른 데이터와 함께 데이터베이스에 저장합니다.

을 쓸 때에 썼다는 수 없기 에) , URL에입니다.찾을 수 없지만(프런트 엔드에 파일이 스토리지에 기록되었음을 알려주는 방법을 찾을 수 없기 때문), 제게 효과적인 것은 공개적으로 사용 가능한 URL에 파일을 쓰고, Firebase에 공개적으로 사용 가능한 URL을 쓰는 것입니다.그러면 내 Angular 프런트 엔드가 Firebase에서 다운로드 URL을 가져올 때도 실행됩니다.getDownloadURL()그러면 토큰이 있는 Firestore의 다운로드 URL과 토큰 다운로드 URL을 비교하고 일치하지 않으면 Firestore에서 공개적으로 사용 가능한 URL 대신 토큰 다운로드 URL을 업데이트합니다.이렇게 하면 파일이 한 번만 공개됩니다.

이것은 듣기보다 쉽습니다.다음 코드는 일련의 스토리지 다운로드 URL을 반복하고 공개적으로 사용 가능한 다운로드 URL을 토큰 다운로드 URL로 바꿉니다.

const storage = getStorage();
var audioFiles: string[] = [];

if (this.pronunciationArray[0].pronunciation != undefined) {
          for (const audioFile of this.pronunciationArray[0].audioFiles) { // for each audio file in array
            let url = await getDownloadURL(ref(storage, audioFile)); // get the download url with token
            if (audioFile !== url) { // download URLs don't match
              audioFiles.push(url);
            } // end inner if
          }; // end for of loop
          if (audioFiles.length > 0) { // update Firestore only if we have new download URLs
            await updateDoc(doc(this.firestore, 'Dictionaries/' + this.l2Language.long + '/Words/' + word + '/Pronunciations/', this.pronunciationArray[0].pronunciation), {
              audioFiles: audioFiles
            });
          }
} // end outer if

"스토리지 위치를 클라우드 기능에서 프런트 엔드로 되돌린 다음 다음,getDownloadURL()토큰 다운로드 URL을 Firestore에 작성합니다."클라우드 기능은 동기식 결과만 반환할 수 있기 때문에 작동하지 않습니다. 반환 비기업반null.

없습니다."라고 당신은 말합니다 옵저버 "옵저버하겠습니다."라고 합니다.getDownloadURL()토큰 다운로드 URL을 Firestore에 작성합니다."주사위는 없습니다.파이어스토어에 옵저버가 있습니다.스토리지에 옵저버가 없습니다.

"프런트 엔드에서 listAll()을 호출하여 모든 스토리지 파일의 목록을 가져온 다음 각 파일의 메타데이터를 호출하고 각 파일의 다운로드 URL과 토큰을 추출한 다음 Firestore에 기록하는 것이 어떻습니까?"라고 말합니다.시도는 잘했지만 스토리지 메타데이터에 다운로드 URL 또는 토큰이 포함되어 있지 않습니다.

서명된 URL 메서드 #1: 임시 다운로드 URL에 대한 getSignedUrl()

getSignedUrl()은 클라우드 기능에서 쉽게 사용할 수 있습니다.

  function oedPromise() {
    return new Promise(function(resolve, reject) {
      http.get(oedAudioURL, function(response) {
        response.pipe(file.createWriteStream(options))
        .on('error', function(error) {
          console.error(error);
          reject(error);
        })
        .on('finish', function() {
          file.getSignedUrl(config, function(err, url) {
            if (err) {
              console.error(err);
              return;
            } else {
              resolve(url);
            }
          });
        });
      });
    });
  }

서명된 다운로드 URL은 다음과 같습니다.

https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio%2FSpanish%2FLatin_America-Sofia-Female-IBM%2Faqu%C3%AD.mp3?GoogleAccessId=languagetwo-cd94d%40appspot.gserviceaccount.com&Expires=4711305600&Signature=WUmABCZIlUp6eg7dKaBFycuO%2Baz5vOGTl29Je%2BNpselq8JSl7%2BIGG1LnCl0AlrHpxVZLxhk0iiqIejj4Qa6pSMx%2FhuBfZLT2Z%2FQhIzEAoyiZFn8xy%2FrhtymjDcpbDKGZYjmWNONFezMgYekNYHi05EPMoHtiUDsP47xHm3XwW9BcbuW6DaWh2UKrCxERy6cJTJ01H9NK1wCUZSMT0%2BUeNpwTvbRwc4aIqSD3UbXSMQlFMxxWbPvf%2B8Q0nEcaAB1qMKwNhw1ofAxSSaJvUdXeLFNVxsjm2V9HX4Y7OIuWwAxtGedLhgSleOP4ErByvGQCZsoO4nljjF97veil62ilaQ%3D%3D

서명된 URL에는 만료 날짜와 긴 서명이 있습니다.gsutil signurl -d 명령줄에 대한 설명서에는 서명된 URL이 임시로 지정되어 있습니다. 기본 만료는 1시간이고 최대 만료는 7일입니다.

getSignedUrl 문서에는 서명된 URL이 일주일 후에 만료된다는 내용이 전혀 없습니다.문서 코드는 다음과 같습니다.3-17-2025만료 날짜로, 향후 만료 연도를 설정할 수 있음을 나타냅니다.제 앱은 완벽하게 작동했고, 일주일 후에 다운되었습니다.다운로드 URL이 만료된 것이 아니라 서명이 일치하지 않는다는 오류 메시지가 표시되었습니다.코드를 다양하게 바꿨습니다. 모든 것이 작동했습니다. 일주일 후에 모든 것이 붕괴될 때까지요.이것은 한 달 이상의 좌절감으로 계속되었습니다.은 ▁이▁is?3-17-2025내막 농담과 데이트?레프르찬이 보이지 않을 때 사라지는 레프르찬의 금화처럼, 미래의 성 패트릭의 날 만료일은 2주 후에 사라집니다. 코드가 버그가 없다고 생각했을 때 말이죠.

공개 URL #1: 파일을 공개적으로 사용할 수 있도록 설정

설명서에 설명된 대로 파일에 대한 권한을 공용 읽기로 설정할 수 있습니다.이 작업은 클라우드 스토리지 브라우저 또는 노드 서버에서 수행할 수 있습니다.하나의 파일을 공용으로 만들거나 디렉터리 또는 전체 저장소 데이터베이스를 만들 수 있습니다.노드 코드는 다음과 같습니다.

var webmPromise = new Promise(function(resolve, reject) {
      var options = {
        destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
        predefinedAcl: 'publicRead',
        contentType: 'audio/' + audioType,
      };

      synthesizeParams.accept = 'audio/webm';
      var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
      textToSpeech.synthesize(synthesizeParams)
      .then(function(audio) {
        audio.pipe(file.createWriteStream(options));
      })
      .then(function() {
        console.log("webm audio file written.");
        resolve();
      })
      .catch(error => console.error(error));
    });

결과는 클라우드 스토리지 브라우저에서 다음과 같이 나타납니다.

enter image description here

그러면 누구나 표준 경로를 사용하여 파일을 다운로드할 수 있습니다.

https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3

파일을 공용으로 만드는 또 다른 방법은 makePublic() 방법을 사용하는 것입니다.이 작업을 수행할 수 없습니다. 버킷 및 파일 경로를 올바르게 지정하기가 어렵습니다.

흥미로운 대안은 접근 제어 목록을 사용하는 것입니다.목록에 추가하거나 사용하는 사용자만 파일을 사용할 수 있습니다.authenticatedReadGoogle 계정에서 로그인한 모든 사용자가 파일을 사용할 수 있도록 설정합니다."Firebase Auth를 사용하여 내 앱에 로그인한 사용자" 옵션이 있다면 내 사용자만 액세스할 수 있기 때문에 이 옵션을 사용할 것입니다.

사용되지 않음:firebaseStorageDownload를 사용하여 나만의 다운로드 URL 구축토큰

되지 않은 속성을 하는 몇 스토리지 개체 속성을 설명합니다.firebaseStorageDownloadTokens이것은 결코 공식적인 Google 클라우드 스토리지 기능이 아니었고 더 이상 작동하지 않습니다.예전에는 이렇습니다.

사용하고자 하는 토큰을 스토리지에 전달했습니다. " 다음토생습니다했성큰을"로 했습니다.uuid코드 . 4줄의 코드를 사용하여 URL을 할 수 .getDownloadURL()코드의 네 줄은 다음과 같습니다.

const uuidv4 = require('uuid/v4');
const uuid = uuidv4();
metadata: { firebaseStorageDownloadTokens: uuid }
https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);

상황에 맞는 코드는 다음과 같습니다.

var webmPromise = new Promise(function(resolve, reject) {
  var options = {
    destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
    contentType: 'audio/' + audioType,
    metadata: {
      metadata: {
        firebaseStorageDownloadTokens: uuid,
      }
    }
  };

      synthesizeParams.accept = 'audio/webm';
      var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
      textToSpeech.synthesize(synthesizeParams)
      .then(function(audio) {
        audio.pipe(file.createWriteStream(options));
      })
      .then(function() {
        resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);
      })
      .catch(error => console.error(error));
});

. 둥지를 . 둥지를 틀어야 합니다.firebaseStorageDownloadTokensmetadata:!

다음은 업로드 시 다운로드 토큰을 지정하는 방법의 예입니다.

const UUID = require("uuid-v4");

const fbId = "<YOUR APP ID>";
const fbKeyFile = "./YOUR_AUTH_FIlE.json";
const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
const bucket = gcs.bucket(`${fbId}.appspot.com`);

var upload = (localFile, remoteFile) => {

  let uuid = UUID();

  return bucket.upload(localFile, {
        destination: remoteFile,
        uploadType: "media",
        metadata: {
          contentType: 'image/png',
          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);
      });
}

그럼 전화를 걸어보세요.

upload(localPath, remotePath).then( downloadURL => {
    console.log(downloadURL);
  });

여기서 핵심적인 것은 다음과 같은 것이 있다는 것입니다.metadata에 내포된 metadata옵션 속성.설정firebaseStorageDownloadTokens토큰으로 합니다.uuid-v4는 Cloud Storage와 동일한 형식으로 사용됩니다.

@martemorfosis에 감사드립니다.

Firebase 프로젝트를 수행하는 경우 다른 라이브러리를 포함하거나 자격 증명 파일을 다운로드하지 않고 Cloud Function에서 서명된 URL을 만들 수 있습니다.IAM API를 활성화하고 기존 서비스 계정에 역할을 추가하기만 하면 됩니다(아래 참조).

관리 라이브러리를 초기화하고 다음과 같이 파일 참조를 가져옵니다.

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

admin.initializeApp(functions.config().firebase)

const myFile = admin.storage().bucket().file('path/to/my/file')

그런 다음 서명된 URL을 생성합니다.

myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
    const signedUrl = urls[0]
})

Firebase 서비스 계정에 이를 실행할 수 있는 충분한 권한이 있는지 확인하십시오.

  1. Google API 콘솔로 이동하여 IAM API(https://console.developers.google.com/apis/api/iam.googleapis.com/overview) 를 활성화합니다.
  2. API 콘솔에서 메인 메뉴인 "IAM & admin" -> "IAM"으로 이동합니다.
  3. "App Engine 기본 서비스 계정" 역할에 대한 편집을 클릭
  4. 다른 역할 추가를 누른 후 "서비스 계정 토큰 작성자"라는 역할을 추가합니다.
  5. 변경 내용이 전파될 때까지 잠시 동안 저장

바닐라 Firebase 구성을 사용하면 위 코드를 처음 실행할 때 IAM(Identity and Access Management) API가 프로젝트 XXXXX에서 이전에 사용되지 않았거나 사용되지 않도록 설정되었다는 오류가 표시됩니다.오류 메시지의 링크를 따라 IAM API를 활성화하면 Permission iam이라는 또 다른 오류가 표시됩니다.서비스 계정 my-service-account에서 이 작업을 수행하려면 serviceAccounts.signBlob이 필요합니다.Token Creator 역할을 추가하면 이 두 번째 권한 문제가 해결됩니다.

특히 대안이 있을 때는 코드에서 URL 접두사를 하코딩하지 않도록 해야 합니다.옵션을 사용하는 것이 좋습니다.predefinedAcl: 'publicRead'Cloud Storage NodeJS 1.6.x 또는 +로 파일을 업로드하는 경우:

const options = {
    destination: yourFileDestination,
    predefinedAcl: 'publicRead'
};

bucket.upload(attachment, options);

그런 다음 공용 URL을 가져오는 작업은 다음과 같이 간단합니다.

bucket.upload(attachment, options).then(result => {
    const file = result[0];
    return file.getMetadata();
}).then(results => {
    const metadata = results[0];
    console.log('metadata=', metadata.mediaLink);
}).catch(error => {
    console.error(error);
});

이것이 제가 현재 사용하는 것이고, 간단하고 완벽하게 작동합니다.

Google Cloud를 사용하여 아무것도 할 필요가 없습니다.Firebase를 사용하면 즉시 사용할 수 있습니다.

// Save the base64 to storage.
const file = admin.storage().bucket('url found on the storage part of firebase').file(`profile_photos/${uid}`);
await file.save(base64Image, {
    metadata: {
      contentType: 'image/jpeg',
    },
    predefinedAcl: 'publicRead'
});
const metaData = await file.getMetadata()
const url = metaData[0].mediaLink

편집: 동일한 예이지만 업로드 시:

await bucket.upload(fromFilePath, {destination: toFilePath});
file = bucket.file(toFilePath);
metaData = await file.getMetadata()
const trimUrl = metaData[0].mediaLink

#update: 메타데이터를 가져오기 위해 업로드 방법에서 두 가지 다른 호출을 할 필요가 없습니다.

let file = await bucket.upload(fromFilePath, {destination: toFilePath});
const trimUrl = file[0].metaData.mediaLink

함수 개체 응답의 최근 변경으로 다운로드 URL을 다음과 같이 "연결"하는 데 필요한 모든 것을 얻을 수 있습니다.

 const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
+ encodeURIComponent(object.name)
+ '?alt=media&token='
+ object.metadata.firebaseStorageDownloadTokens;

console.log('URL',img_url);

Firebase Admin SDK service AccountKey.json 파일의 위치를 알고 싶은 분들을 위해.그냥 functions 폴더에 넣고 평소처럼 배포하면 됩니다.

자바스크립트 SDK에서처럼 메타데이터에서 다운로드 URL을 가져올 수 없는 이유는 아직도 이해할 수 없습니다. 결국 만료될 URL을 생성하여 데이터베이스에 저장하는 것은 바람직하지 않습니다.

하는 한 을 성적것다사한 UUID v4 을공이입라는 이름의 입니다.firebaseStorageDownloadTokens된 후 URL을 후 URL을 다운로드 URL을 구성합니다. 예 firebase 업 일 로 firebase 을 한 생 구 따 을 는 조 에 다 다 라 조 니 운 합 립 직 로 접 파 드 하 용 사 가 데 드 는 하 가 성 완 일 타러료파된 데 이 후 터 에 서 의 메 이 ▁in 예:

https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]

(파이어베이스가 향후 다운로드 URL을 생성하는 방법을 변경할 수 있다는 점을 고려할 때) 이 방법을 사용하는 것이 얼마나 "안전한지" 모르겠지만 구현하기 쉽습니다.

죄송하지만 위 질문에 대한 의견을 올릴 수 없는 이유는 평판이 좋지 않기 때문에 이 답변에 포함시키겠습니다.

위에서 언급한 대로 서명된 URL을 생성하지만 service-account.json을 사용하는 대신 생성할 수 있는 serviceAccountKey.json을 사용해야 한다고 생각합니다(그에 따라 프로젝트 ID를 교체하십시오).

https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk

예:

const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
// ...
const bucket = gcs.bucket(bucket);
// ...
return bucket.upload(tempLocalFile, {
        destination: filePath,
        metadata: {
          contentType: 'image/jpeg'
        }
      })
      .then((data) => {
        let file = data[0]
        file.getSignedUrl({
          action: 'read',
          expires: '03-17-2025'
        }, function(err, url) {
          if (err) {
            console.error(err);
            return;
          }

          // handle url 
        })

James Daniels가 한 대답에 대해 언급할 수 없지만, 저는 이것이 읽기에 매우 중요하다고 생각합니다.

그가 했던 것처럼 서명된 URL을 제공하는 것은 많은 경우에 매우 나쁘고 위험할 수 있습니다.Firebase의 문서에 따르면 서명된 URL은 시간이 지나면 만료되므로 데이터베이스에 추가하면 일정 기간이 지나면 빈 URL이 됩니다.

설명서를 잘못 이해하여 서명된 URL이 만료되지 않아 보안 문제가 발생할 수 있습니다.업로드된 모든 파일에 대해 키가 동일한 것 같습니다.즉, 한 파일의 URL을 알게 되면 다른 사용자가 이름만 알고도 액세스할 수 없는 파일에 쉽게 액세스할 수 있습니다.

만약 내가 그것을 잘못 이해했다면 나는 수정될 것입니다.그렇지 않으면 다른 사용자가 위의 지정된 솔루션을 업데이트해야 합니다.만약 내가 틀릴지도 모르지만 거기서.

사용하다file.publicUrl()

비동기/대기

const bucket = storage.bucket('bucket-name');
const uploadResponse = await bucket.upload('image-name.jpg');
const downloadUrl = uploadResponse[0].publicUrl();

콜백

const bucket = storage.bucket('bucket-name');
bucket.upload('image-name.jpg', (err, file) => {
  if(!file) {
    throw err;
  }

  const downloadUrl = file.publicUrl();
})

downloadUrl▁▁be 될 것입니다."https://storage.googleapis.com/bucket-name/image-name.jpg".

위 코드가 작동하려면 버킷 또는 파일을 공개해야 합니다.그렇게 하려면 여기 https://cloud.google.com/storage/docs/access-control/making-data-public 의 지침을 따르십시오.또한, 저는 그것을 수입했습니다.@google-cloud/storage패키지는 Firebase SDK를 통해 직접 생성되지 않습니다.

미리 정의된 액세스 제어 목록 값인 'publicRead'를 사용하면 파일을 업로드하고 매우 간단한 URL 구조로 액세스할 수 있습니다.

// Upload to GCS
const opts: UploadOptions = {
  gzip: true,
  destination: dest, // 'someFolder/image.jpg'
  predefinedAcl: 'publicRead',
  public: true
};
return bucket.upload(imagePath, opts);

그런 다음 다음과 같이 URL을 구성할 수 있습니다.

const storageRoot = 'https://storage.googleapis.com/';
const bucketName = 'myapp.appspot.com/'; // CHANGE TO YOUR BUCKET NAME
const downloadUrl = storageRoot + bucketName + encodeURIComponent(dest);

저도 같은 문제가 있었습니다. 하지만 README 대신 파이어베이스 함수 예제의 코드를 보고 있었습니다. 그리고 이 스레드에 대한 답변도 도움이 되지 않았습니다.

다음을 수행하여 구성 파일이 전달되지 않도록 할 수 있습니다.

프로젝트의 클라우드 콘솔 > IAM & admin > IAM으로 이동하여 App Engine 기본 서비스 계정을 찾고 서비스 계정 토큰 생성자 역할을 해당 구성원에 추가합니다.이렇게 하면 앱이 이미지에 서명된 공개 URL을 만들 수 있습니다.

source: 자동으로 썸네일 생성 기능 README

앱 엔진의 역할은 다음과 같습니다.

Cloud Console

https://stackoverflow.com/users/269447/laurent 의 답변이 가장 잘 작동합니다.

const uploadOptions: UploadOptions = {
    public: true
};

const bucket = admin.storage().bucket();
[ffile] = await bucket.upload(oPath, uploadOptions);
ffile.metadata.mediaLink // this is what you need

이 기능은 단순 URL이 포함된 공용 파일이 필요한 경우에만 작동합니다. Firebase 저장소 규칙을 무시할 수 있습니다.

bucket.upload(file, function(err, file) {
    if (!err) {
      //Make the file public
      file.acl.add({
      entity: 'allUsers',
      role: gcs.acl.READER_ROLE
      }, function(err, aclObject) {
          if (!err) {
              var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
              console.log(URL);
          } else {
              console.log("Failed to set permissions: " + err);
          }
      });  
    } else {
        console.log("Upload failed: " + err);
    }
});

없이.signedURL()용사를 makePublic()

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp()
var bucket = admin.storage().bucket();

// --- [Above] for admin related operations, [Below] for making a public url from a GCS uploaded object

const { Storage } = require('@google-cloud/storage');
const storage = new Storage();

exports.testDlUrl = functions.storage.object().onFinalize(async (objMetadata) => {
    console.log('bucket, file', objMetadata.bucket + ' ' + objMetadata.name.split('/').pop()); // assuming file is in folder
    return storage.bucket(objMetadata.bucket).file(objMetadata.name).makePublic().then(function (data) {
        return admin.firestore().collection('publicUrl').doc().set({ publicUrl: 'https://storage.googleapis.com/' + objMetadata.bucket + '/' + objMetadata.name }).then(writeResult => {
            return console.log('publicUrl', writeResult);
        });
    });
});

나는 이것을 관리 스토리지 문서에서 보았습니다.

const options = {
  version: 'v4',
  action: 'read',
  expires: Date.now() + 15 * 60 * 1000, // 15 minutes
};

// Get a v4 signed URL for reading the file
const [url] = await storage
  .bucket(bucketName)
  .file(filename)
  .getSignedUrl(options);

console.log('Generated GET signed URL:');
console.log(url);
console.log('You can use this URL with any user agent, for example:');
console.log(`curl '${url}'`);

SDK 및 Firebase SDK를 admin.initializeApp:

1 - 개인 키를 생성하고 /functions 폴더에 배치합니다.

2 - 다음과 같이 코드를 구성합니다.

const serviceAccount = require('../../serviceAccountKey.json');
try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}

문서화

try 각입니다.try/catch는 파일마다 하나의 함수를 만듭니다.index 함수와 index.js index. 파일을 참조하십시오.admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.

Firebase 6.0.0 이후에는 다음과 같이 관리자와 함께 스토리지에 직접 액세스할 수 있었습니다.

const bucket = admin.storage().bucket();

그래서 서비스 계정을 추가할 필요가 없었습니다.그런 다음 위에서 참조한 대로 UUID를 설정하면 Firebase URL을 가져올 수 있습니다.

이게 내가 생각한 최고야.그것은 중복적이지만 저에게 효과가 있는 유일한 합리적인 해결책입니다.

await bucket.upload(localFilePath, {destination: uploadPath, public: true});
const f = await bucket.file(uploadPath)
const meta = await f.getMetadata()
console.log(meta[0].mediaLink)

이미 답을 올렸습니다...솔루션과 함께 전체 코드를 얻을 수 있는 아래 URL에서

Node.js를 사용하여 Base64 인코딩 이미지(문자열)를 Google Cloud Storage 버킷에 직접 업로드하려면 어떻게 해야 합니까?

const uuidv4 = require('uuid/v4');
const uuid = uuidv4();

    const os = require('os')
    const path = require('path')
    const cors = require('cors')({ origin: true })
    const Busboy = require('busboy')
    const fs = require('fs')
    var admin = require("firebase-admin");


    var serviceAccount = {
        "type": "service_account",
        "project_id": "xxxxxx",
        "private_key_id": "xxxxxx",
        "private_key": "-----BEGIN PRIVATE KEY-----\jr5x+4AvctKLonBafg\nElTg3Cj7pAEbUfIO9I44zZ8=\n-----END PRIVATE KEY-----\n",
        "client_email": "xxxx@xxxx.iam.gserviceaccount.com",
        "client_id": "xxxxxxxx",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-5rmdm%40xxxxx.iam.gserviceaccount.com"
      }

    admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
        storageBucket: "xxxxx-xxxx" // use your storage bucket name
    });


    const app = express();
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(bodyParser.json());
app.post('/uploadFile', (req, response) => {
    response.set('Access-Control-Allow-Origin', '*');
    const busboy = new Busboy({ headers: req.headers })
    let uploadData = null
    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        const filepath = path.join(os.tmpdir(), filename)
        uploadData = { file: filepath, type: mimetype }
        console.log("-------------->>",filepath)
        file.pipe(fs.createWriteStream(filepath))
      })

      busboy.on('finish', () => {
        const bucket = admin.storage().bucket();
        bucket.upload(uploadData.file, {
            uploadType: 'media',
            metadata: {
              metadata: { firebaseStorageDownloadTokens: uuid,
                contentType: uploadData.type,
              },
            },
          })

          .catch(err => {
            res.status(500).json({
              error: err,
            })
          })
      })
      busboy.end(req.rawBody)
   });




exports.widgets = functions.https.onRequest(app);

토큰 매개 변수를 사용하여 파일을 공유하고 gsutil 명령을 사용하려는 사용자를 위해 다음과 같이 작업했습니다.

다음을.gcloud auth

그런 다음 실행:

gsutil setmeta -h "x-goog-meta-firebaseStorageDownloadTokens:$FILE_TOKEN" gs://$FIREBASE_REPO/$FILE_NAME

그런 다음 다음 링크를 사용하여 파일을 다운로드할 수 있습니다.

https://firebasestorage.googleapis.com/v0/b/$FIREBASE_REPO/o/$FILE_NAME?alt=media&token=$FILE_TOKEN

관리 SDK에서는 업로드된 파일의 Firebase에서 생성된 다운로드 토큰을 검색할 수 없지만 업로드 시 메타데이터에 추가하여 해당 토큰을 설정할 수 있습니다.

Python SDK에서 작업 중인 사용자를 위한 것입니다.다음과 같은 방법이 있습니다.

from firebase_admin import storage
from uuid import uuid4

bucket = storage.bucket()
blob = bucket.blob(path_to_file)
token = str(uuid4()) # Random ID

blob.metadata = {
        "firebaseStorageDownloadTokens": token
    }
blob.upload_from_file(file)

이제 파일을 업로드하고 URL 토큰을 받았습니다.이제 토큰(또는 전체 다운로드 URL)을 데이터베이스(예: Firestore)에 저장하고 파일이 요청될 때 클라이언트로 전송한 다음 클라이언트가 직접 파일을 검색하도록 할 수 있습니다.

전체 다운로드 URL은 다음과 같습니다.

https://firebasestorage.googleapis.com/v0/b/{bucket_name}/o/{file_name}?alt=media&token={token}

오류가 발생하는 경우:

Google 클라우드 기능: require(…)는 기능이 아닙니다.

사용해 보십시오.

const {Storage} = require('@google-cloud/storage');
const storage = new Storage({keyFilename: 'service-account-key.json'});
const bucket = storage.bucket(object.bucket);
const file = bucket.file(filePath);
.....

tldr; 블로그 업로드이미지 가져오기Urldr

const file = storage.bucket().file(`images/${imageName}.jpeg`)

await file.save(image)

const imgUrl = file.metadata.mediaLink

언급URL : https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud-functions-for-firebase

반응형