Florian T
Florian T

Reputation: 142

Read file with firebase function

I've got a Firebase Function and want to read a html file, stored in a subfolder.

── functions
    ├── src
    |   ├── index.ts // Here is the function
    |   ├── html
    |   |   ├── template.html // the file I want to read

I tried to read the file via const html = fs.readFileSync('./html/template.html'); but it always tells me

Error: ENOENT: no such file or directory, open './html/template.html' at Object.openSync

I worked trough almost every question on stackoverflow concerning this topic but nothing worked for me. I also tried placing the file in the same folder as the function but it always gives me the error.

Do I need to install some package or import the file in some way to access it?

Upvotes: 5

Views: 4456

Answers (2)

nVitius
nVitius

Reputation: 2214

For anyone coming into this post from the search results...

The solution to this isn't using path.resolve.

The problem here is that, fs.readFileSync resolves paths relative to process.cwd() (the directory node was executed from). In the case of firebase functions, this will always be the directory defined for source in firebase.json (by default, the functions directory).
This functionality is documented here:
https://nodejs.org/api/path.html#path_path_resolve_paths

If, after processing all given path segments, an absolute path has not yet been generated, the current working directory is used.

path.resolve has the same behavior. It always resolves to an absolute path. If the path you pass in is not absolute, it prepends process.cwd() to it.
It doesn't look like this is documented in the Node docs, but you can see for yourself here: https://github.com/nodejs/node/blob/029d1fd797975ef89b867f9d606257f0f070a462/lib/path.js#L1017

You can solve this in two ways:

  • Using a path relative to your functions root dir (src/html/template.html in this case)
  • Using __dirname (path.resolve(__dirname, './html/template.html')

__dirname is a variable that will always return an absolute path to the directory of the current file that is being executed.

Upvotes: 12

Renaud Tarnec
Renaud Tarnec

Reputation: 83181

You need to use the path.resolve() method, which will resolve your path into an absolute path, before passing it to the fs.readdirSync() method. So the following should do the trick:

    const path = require('path');

    // ...

    let content = fs.readFileSync(
        path.resolve('./html/template.html')
    );

Upvotes: 4

Related Questions