Po przesłaniu pliku do Firebase Storage za pomocą Funkcji Firebase chcę uzyskać adres URL pobierania pliku.
Mam to :
...
return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {
// Get the download url of file
});
Plik obiektowy ma wiele parametrów. Nawet jeden nazwany mediaLink
. Jeśli jednak spróbuję uzyskać dostęp do tego linku, pojawia się ten błąd:
Użytkownicy anonimowi nie mają dostępu do obiektu storage.objects.get ...
Czy ktoś może mi powiedzieć, jak uzyskać publiczny adres URL pobierania?
Dziękuję Ci
Odpowiedzi:
Musisz wygenerować podpisany adres URL przy użyciu getSignedURL za pośrednictwem modułu @ google-cloud / storage NPM.
Przykład:
Konieczne będzie zainicjowanie
@google-cloud/storage
przy użyciu poświadczeń konta usługi, ponieważ domyślne poświadczenia aplikacji nie będą wystarczające.AKTUALIZACJA : Dostęp do pakietu Cloud Storage SDK można teraz uzyskać za pośrednictwem pakietu Firebase Admin SDK, który działa jako opakowanie wokół @ google-cloud / storage. Jedynym sposobem jest, jeśli:
źródło
action
iexpires
?Oto przykład, jak określić token pobierania podczas przesyłania:
następnie zadzwoń z
Kluczową rzeczą jest to, że
metadata
wemetadata
właściwości opcji znajduje się obiekt zagnieżdżony . UstawieniefirebaseStorageDownloadTokens
wartości uuid-v4 spowoduje, że Cloud Storage użyje go jako publicznego tokenu uwierzytelniania.Wielkie dzięki dla @martemorfosis
źródło
Ta odpowiedź zawiera podsumowanie opcji pobierania adresu URL pobierania podczas przesyłania pliku do Google / Firebase Cloud Storage. Istnieją trzy typy adresów URL pobierania:
Istnieją trzy sposoby uzyskania adresu URL pobierania tokena. Pozostałe dwa adresy URL pobierania mają tylko jeden sposób, aby je uzyskać.
Z konsoli Firebase Storage
Adres URL pobierania możesz uzyskać z konsoli Firebase Storage:
Adres URL pobierania wygląda następująco:
Pierwsza część to standardowa ścieżka do Twojego pliku. Na końcu jest token. Ten adres URL pobierania jest trwały, tj. Nie wygaśnie, chociaż można go cofnąć.
getDownloadURL () z interfejsu użytkownika
Dokumentacja mówi nam do wykorzystania
getDownloadURL()
:Otrzymuje ten sam adres URL pobierania, który możesz pobrać z konsoli Firebase Storage. Ta metoda jest łatwa, ale wymaga znajomości ścieżki do pliku, który w mojej aplikacji zawiera około 300 linii kodu, aby uzyskać stosunkowo prostą strukturę bazy danych. Jeśli twoja baza danych jest złożona, byłby to koszmar. Możesz przesyłać pliki z poziomu interfejsu użytkownika, ale spowoduje to ujawnienie Twoich danych uwierzytelniających każdemu, kto pobierze Twoją aplikację. Dlatego w przypadku większości projektów będziesz chciał przesłać pliki z zaplecza Node lub Google Cloud Functions, a następnie uzyskać adres URL pobierania i zapisać go w bazie danych wraz z innymi danymi o pliku.
getSignedUrl () dla tymczasowych adresów URL pobierania
getSignedUrl () jest łatwy w użyciu z zaplecza Node lub Google Cloud Functions:
Podpisany adres URL pobierania wygląda następująco:
Podpisany adres URL ma datę ważności i długi podpis. Dokumentacja dotycząca wiersza poleceń gsutil signurl -d mówi, że podpisane adresy URL są tymczasowe: domyślny okres ważności to jedna godzina, a maksymalny okres ważności to siedem dni.
Mam zamiar ogłosić, że getSignedUrl nigdy nie mówi, że Twój podpisany adres URL wygaśnie za tydzień. Kod dokumentacji ma
3-17-2025
datę wygaśnięcia, co sugeruje, że można ustawić lata wygaśnięcia w przyszłości. Moja aplikacja działała idealnie, a tydzień później uległa awarii. Komunikat o błędzie mówił, że podpisy nie pasują, a nie że adres URL pobierania wygasł. Wprowadziłem różne zmiany w moim kodzie i wszystko działało ... aż wszystko się zawiesiło tydzień później. Trwało to ponad miesiąc frustracji.Udostępnij plik publicznie
Możesz ustawić uprawnienia do publicznego odczytu pliku, jak wyjaśniono w dokumentacji . Można to zrobić z przeglądarki Cloud Storage lub z serwera Node. Możesz ustawić jeden plik jako publiczny, katalog lub całą bazę danych magazynu. Oto kod węzła:
Wynik będzie wyglądał następująco w przeglądarce Cloud Storage:
Każdy może następnie użyć standardowej ścieżki do pobrania pliku:
Innym sposobem na upublicznienie pliku jest użycie metody makePublic () . Nie udało mi się to uruchomić, trudno jest poprawnie ustawić zasobnik i ścieżki plików.
Ciekawą alternatywą jest użycie list kontroli dostępu . Możesz udostępnić plik tylko użytkownikom, których umieścisz na liście, lub użyć go,
authenticatedRead
aby udostępnić plik każdemu, kto jest zalogowany z konta Google. Gdyby istniała opcja „każdy, kto logował się do mojej aplikacji przy użyciu uwierzytelniania Firebase”, użyłbym tej opcji, ponieważ ograniczyłaby dostęp tylko do moich użytkowników.Zbuduj własny adres URL pobierania za pomocą firebaseStorageDownloadTokens
W kilku odpowiedziach opisano nieudokumentowaną właściwość obiektu Google Storage
firebaseStorageDownloadTokens
. Dzięki temu możesz wskazać Storage token, którego chcesz użyć. Możesz wygenerować token za pomocąuuid
modułu Node. Cztery wiersze kodu i możesz utworzyć własny adres URL pobierania, ten sam adres URL pobierania, który otrzymasz z konsoli lubgetDownloadURL()
. Cztery wiersze kodu to:Oto kod w kontekście:
To nie jest literówka - musisz zagnieździć się
firebaseStorageDownloadTokens
w podwójnych warstwachmetadata:
!Doug Stevenson zwrócił uwagę, że
firebaseStorageDownloadTokens
nie jest to oficjalna funkcja Google Cloud Storage. Nie znajdziesz go w żadnej dokumentacji Google i nie ma obietnic, że będzie w przyszłej wersji@google-cloud
. Lubię,firebaseStorageDownloadTokens
ponieważ jest to jedyny sposób na zdobycie tego, czego chcę, ale ma „zapach”, którego nie jest bezpieczny w użyciu.Dlaczego nie ma metody getDownloadURL () z węzła?
Jak napisał @Clinton, Google powinien utworzyć
file.getDownloadURL()
metodę w@google-cloud/storage
(tj. Zapleczu Twojego Node). Chcę przesłać plik z Google Cloud Functions i uzyskać adres URL pobierania tokena.źródło
@google-cloud/storage
tym celu, możesz dać mu +1;) github.com/googleapis/nodejs-storage/issues/697firebaseStorageDownloadTokens
to, że już nie działa.Dzięki niedawnym zmianom w odpowiedzi obiektu funkcji możesz uzyskać wszystko, czego potrzebujesz, aby „zszyć” adres URL pobierania w następujący sposób:
źródło
bucket.file().upload()
? Nie otrzymuję żadnej właściwości metadanych w danych odpowiedzi i nie jestem pewien, jak je uzyskaćfirebaseStorageDownloadTokens
.bucket.name
, że nie musisz go na stałemetadata.mediaLink
nieruchomości zapobiega takim problemom.Jeśli pracujesz nad projektem Firebase, możesz tworzyć podpisane adresy URL w Cloud Function bez dołączania innych bibliotek lub pobierania pliku danych logowania. Wystarczy włączyć IAM API i dodać rolę do istniejącego konta usługi (patrz poniżej).
Zainicjuj bibliotekę administratora i uzyskaj odniesienie do pliku w normalny sposób:
Następnie generujesz podpisany adres URL z
Upewnij się, że Twoje konto usługi Firebase ma wystarczające uprawnienia, aby to uruchomić
W przypadku podstawowej konfiguracji Firebase przy pierwszym uruchomieniu powyższego kodu pojawi się błąd API zarządzania tożsamością i dostępem (IAM), które nie było wcześniej używane w projekcie XXXXXX lub jest wyłączone. . Jeśli klikniesz łącze w komunikacie o błędzie i włączysz IAM API, pojawi się kolejny błąd: Uprawnienie iam.serviceAccounts.signBlob jest wymagane do wykonania tej operacji na koncie usługi moje-konto-usługi . Dodanie roli Twórca tokenów rozwiązuje ten drugi problem z uprawnieniami.
źródło
Jedną z metod, których używam z powodzeniem, jest ustawienie wartości UUID v4 na klucz nazwany
firebaseStorageDownloadTokens
w metadanych pliku po zakończeniu przesyłania, a następnie samodzielne zestawienie adresu URL pobierania zgodnie ze strukturą używaną przez Firebase do generowania tych adresów URL, np .:Nie wiem, jak bardzo „bezpieczne” jest używanie tej metody (biorąc pod uwagę, że Firebase może zmienić sposób generowania adresów URL pobierania w przyszłości), ale jest łatwa do wdrożenia.
źródło
Dla tych, którzy zastanawiają się, gdzie powinien znaleźć się plik serviceAccountKey.json pakietu Firebase Admin SDK. Po prostu umieść go w folderze funkcji i wdróż jak zwykle.
Wciąż zdumiewa mnie, dlaczego nie możemy po prostu pobrać adresu URL z metadanych, tak jak robimy to w SDK JavaScript. Generowanie adresu URL, który ostatecznie wygaśnie, i zapisanie go w bazie danych nie jest pożądane.
źródło
Należy unikać przedrostka adresu URL harcoding w swoim kodzie . Proponuję skorzystać z opcji
predefinedAcl: 'publicRead'
przy wgrywaniu pliku z Cloud Storage NodeJS 1.6.x lub +:Uzyskanie publicznego adresu URL jest wtedy tak proste, jak:
źródło
Przepraszamy, ale nie mogę opublikować komentarza do Twojego pytania powyżej z powodu braku reputacji, więc dołączę go do tej odpowiedzi.
Zrób tak, jak opisano powyżej, generując podpisany adres URL, ale zamiast korzystać z service-account.json, myślę, że musisz użyć serviceAccountKey.json, który możesz wygenerować pod adresem (odpowiednio zastąp YOURPROJECTID)
https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk
Przykład:
źródło
Nie mogę komentować odpowiedzi, której udzielił James Daniels, ale myślę, że jest to bardzo ważne do przeczytania.
Wydanie podpisanego adresu URL Wydaje się, że w wielu przypadkach jest dość zły i prawdopodobnie Niebezpieczny . Zgodnie z dokumentacją Firebase, podpisany adres URL wygasa po pewnym czasie, więc dodanie go do bazy danych doprowadzi do pustego adresu URL po pewnym czasie
Może się zdarzyć, że dokumentacja została tam źle zrozumiana, a podpisany adres URL nie wygasa, co spowodowałoby pewne problemy z bezpieczeństwem. Klucz wydaje się być taki sam dla każdego przesłanego pliku. Oznacza to, że po uzyskaniu adresu URL jednego pliku ktoś może łatwo uzyskać dostęp do plików, do których nie powinien mieć dostępu, znając tylko ich nazwy.
Gdybym tego nie zrozumiał, wolałbym zostać poprawiony. W przeciwnym razie ktoś powinien prawdopodobnie zaktualizować powyższe rozwiązanie. Jeśli się mylę
źródło
To jest to, czego obecnie używam, jest proste i działa bez zarzutu.
Nie musisz nic robić z Google Cloud. Działa po wyjęciu z pudełka z Firebase.
EDYCJA: ten sam przykład, ale z przesyłaniem:
#update: nie ma potrzeby wykonywania dwóch różnych wywołań w metodzie przesyłania, aby uzyskać metadane:
źródło
Jeśli używasz wstępnie zdefiniowanej wartości list kontroli dostępu „publicRead”, możesz przesłać plik i uzyskać do niego dostęp z bardzo prostą strukturą adresu URL:
Następnie możesz utworzyć adres URL w następujący sposób:
źródło
Miałem ten sam problem, jednak patrzyłem na kod przykładu funkcji firebase zamiast README. Odpowiedzi w tym wątku też nie pomogły ...
Możesz uniknąć przekazywania pliku konfiguracyjnego, wykonując następujące czynności:
źródło: funkcja automatycznego generowania miniatur README
Twoja rola dla silnika aplikacji powinna wyglądać następująco:
źródło
Działa to, jeśli potrzebujesz tylko publicznego pliku z prostym adresem URL. Pamiętaj, że może to unieważnić reguły przechowywania w Firebase.
źródło
Dla tych, którzy używają Firebase SDK i
admin.initializeApp
:1 - Wygeneruj klucz prywatny i umieść go w folderze / functions.
2 - Skonfiguruj swój kod w następujący sposób:
Dokumentacja
Try / catch jest spowodowane tym, że używam pliku index.js, który importuje inne pliki i tworzy jedną funkcję dla każdego pliku. Jeśli używasz jednego pliku index.js ze wszystkimi funkcjami, powinieneś być w porządku
admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));
.źródło
Od Firebase 6.0.0 mogłem uzyskać dostęp do pamięci bezpośrednio z administratorem w następujący sposób:
Więc nie musiałem dodawać konta usługi. Następnie ustawienie UUID, jak wspomniano powyżej, pomogło w uzyskaniu adresu URL Firebase.
źródło
To najlepsze, co wymyśliłem. Jest to zbędne, ale jedyne rozsądne rozwiązanie, które u mnie zadziałało.
źródło
Bez
signedURL()
użyciamakePublic()
źródło
odpowiedź przez https://stackoverflow.com/users/269447/laurent działa najlepiej
źródło
Jeśli otrzymujesz błąd:
Spróbuj tego:
źródło
Już wysyłam moje odpowiedzi ... w poniższy adres URL, gdzie można uzyskać pełny kod z rozwiązaniem
Jak przesłać obraz (ciąg znaków) zakodowany w base64 bezpośrednio do zasobnika Google Cloud Storage przy użyciu Node.js?
źródło