Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Public URL from file uploaded with firebase-admin

I use firebase-admin and firebase-functions to upload a file in Firebase Storage.

I have this rules in storage:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      allow read;
      allow write: if false;
    }
  }
}

And I want get a public URL with this code:

const config = functions.config().firebase;
const firebase = admin.initializeApp(config);
const bucketRef = firebase.storage();

server.post('/upload', async (req, res) => {

  // UPLOAD FILE

  await stream.on('finish', async () => {
        const fileUrl = bucketRef
          .child(`images/${fileName}`)
          .getDownloadUrl()
          .getResult();
        return res.status(200).send(fileUrl);
      });
});

But I have this error .child is not a function. How can I get the public url of a file with firebase-admin?

like image 493
SaroVin Avatar asked Nov 02 '17 10:11

SaroVin


People also ask

How do I get the URL of uploaded files on Firebase storage?

You can use StorageReference. getDownloadUrl(). why is there a need to attach an addOnSuccessListener with getDownloadUrl() ? since the path where the file is uploaded is a very small string, i assume there must be a way to retrieve the path from the taskSnapshot recieved in ..

How do I get Firebase storage path?

String path = storageReference. getPath();

How do I get the download URL from Firebase storage in react native?

Download URLs To generate a new Download URL, you need to call the getDownloadURL method on a reference: import storage from '@react-native-firebase/storage'; const url = await storage(). ref('images/profile-1. png').


2 Answers

From the sample application code on the using Cloud Storage documentation, you should be able to implement the following code to obtain the public download URL after the upload is successful:

// Create a new blob in the bucket and upload the file data.
const blob = bucket.file(req.file.originalname);
const blobStream = blob.createWriteStream();

blobStream.on('finish', () => {
    // The public URL can be used to directly access the file via HTTP.
    const publicUrl = format(`https://storage.googleapis.com/${bucket.name}/${blob.name}`);
    res.status(200).send(publicUrl);
});

Alternatively, if you need a publicly accessible download URL, see this answer which suggests using getSignedUrl() from the Cloud Storage NPM module because the Admin SDK doesn't support this directly:

You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.

Example:

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
});
like image 128
Grimthorr Avatar answered Oct 24 '22 21:10

Grimthorr


I've been tinkering with this for days and realized

A) correct access rights on the bucket is key:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read;
      allow write: if request.auth != null;
    }
  }
}

B) The functional public URL is right there in the meta data (tested and works). Notice the access rights.

  const pdfDoc = printer.createPdfKitDocument(docDefinition);
  const pdfFile = admin
      .storage()
      .bucket()
      .file(newId + '.pdf');

    pdfDoc.pipe(
      pdfFile.createWriteStream({
        contentType: 'application/pdf',
        public: true,
      })
    );
    pdfDoc.end();

    console.log('Get public URL');
    const publicUrl = pdfFile.metadata.mediaLink;
like image 23
Thomas Hagström Avatar answered Oct 24 '22 20:10

Thomas Hagström