Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file.makePublic() support in Storage Emulator #3394

Closed
itsravenous opened this issue May 21, 2021 · 1 comment · Fixed by #3403
Closed

Add file.makePublic() support in Storage Emulator #3394

itsravenous opened this issue May 21, 2021 · 1 comment · Fixed by #3403

Comments

@itsravenous
Copy link

itsravenous commented May 21, 2021

[REQUIRED] Environment info

firebase-tools: 9.11.0

Platform: Manjaro Linux

[REQUIRED] Test case

upload-test.js:

const admin = require('firebase-admin');
const serviceAccount = require("./serviceAccount.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  storageBucket: `${serviceAccount.project_id}.appspot.com`,
});

async function uploadTest() {
  // Get storage bucket ref
  const bucket = admin.storage().bucket();

  const image = "./my-image.jpg";
  // Upload it
  const [file] = await bucket.upload(image);

  console.log(`uploaded ${image}`);

  // Make public
  try {
    await file.makePublic();
  } catch (err) {
    console.error("error making file public", err);
  }

  // Get public URL
  console.log(file.publicUrl());
}

uploadTest()

[REQUIRED] Steps to reproduce

Terminal 1:

firebase emulators:start

Terminal 2:

FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 FIRESTORE_EMULATOR_HOST=localhost:8080 FIREBASE_STORAGE_EMULATOR_HOST=localhost:9199 node upload-test.js

[REQUIRED] Expected behavior

The public URL of the file is printed to the terminal.

[REQUIRED] Actual behavior

The file is present in the storage emulator UI, and is listed as having the correct size, but the file.makePublic() call is failing - see entire output below:

uploaded ./my-image.jpg
error making file public ApiError: Not Found
    at new ApiError (/home/xxx/dev/my-project/node_modules/@google-cloud/common/build/src/util.js:59:15)
    at Util.parseHttpRespMessage (/home/xxx/dev/my-project/node_modules/@google-cloud/common/build/src/util.js:161:41)
    at Util.handleResp (/home/xxx/dev/my-project/node_modules/@google-cloud/common/build/src/util.js:135:76)
    at /home/xxx/dev/my-project/node_modules/@google-cloud/common/build/src/util.js:434:22
    at onResponse (/home/xxx/dev/my-project/node_modules/retry-request/index.js:214:7)
    at /home/xxx/dev/my-project/node_modules/teeny-request/build/src/index.js:219:13
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  code: 404,
  errors: [],
  response: PassThrough {
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: null,
      pipesCount: 0,
      flowing: true,
      ended: true,
      endEmitted: true,
      reading: false,
      sync: false,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      emitClose: true,
      autoDestroy: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    readable: false,
    _events: [Object: null prototype] {
      prefinish: [Function: prefinish],
      error: [Array],
      data: [Function],
      end: [Function]
    },
    _eventsCount: 4,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: true,
      ended: true,
      finished: true,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: true,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: [Object]
    },
    writable: false,
    allowHalfOpen: true,
    _transformState: {
      afterTransform: [Function: bound afterTransform],
      needTransform: false,
      transforming: false,
      writecb: null,
      writechunk: null,
      writeencoding: 'buffer'
    },
    statusCode: 404,
    statusMessage: 'Not Found',
    request: {
      agent: [Agent],
      headers: [Object],
      href: 'http://localhost:9199/b/track-stage-ee818.appspot.com/o/male.jpg/acl?'
    },
    body: 'Not Found',
    headers: {
      'access-control-expose-headers': 'content-type,x-firebase-storage-version,x-goog-upload-url,x-goog-upload-status,x-goog-upload-command,x-gupload-uploadid,x-goog-upload-header-content-length,x-goog-upload-header-content-type,x-goog-upload-protocol,x-goog-upload-status,x-goog-upload-chunk-granularity,x-goog-upload-control-url',
      connection: 'keep-alive',
      'content-length': '9',
      'content-type': 'text/plain; charset=utf-8',
      date: 'Fri, 21 May 2021 15:02:36 GMT',
      etag: 'W/"9-0gXL1ngzMqISxa6S1zx3F4wtLyg"',
      'keep-alive': 'timeout=5',
      vary: 'Origin',
      'x-powered-by': 'Express'
    },
    toJSON: [Function: toJSON],
    [Symbol(kCapture)]: false
  }
}
@abeisgoat
Copy link
Contributor

This is a known issue, a fix is coming this week!

In the meantime you can work around it by using read: true in your storage rules and using the Firebase Storage URLs instead of Cloud's.

If your Storage security rules support unauthenticated reads you can just generate a url likehttps://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeUriComponent(pathToFile)}?alt=media and it'll be public. For example, here's a file in my public bucket https://firebasestorage.googleapis.com/v0/b/abe-today.appspot.com/o/public%2F1_3_Bill.png?alt=media, it's a little different, but its a bit more Firebasey :)

@abeisgoat abeisgoat changed the title file.makePublic() doesn't work with storage emulator Add file.makePublic() support in Storage Emulator May 25, 2021
abeisgoat added a commit that referenced this issue May 25, 2021
abeisgoat added a commit that referenced this issue May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants