Module not found: Can't resolve 'fs' on @google-cloud/storage
Asked Answered
T

5

8

Getting the Module not found: Can't resolve 'fs' error when trying to list out buckets from GCP Storage.

import { Storage } from '@google-cloud/storage';

const googleCloud = new Storage({
  keyFilename: '../../my-project-c1a44bf80be3.json',
  projectId: 'my-project',
});

googleCloud.getBuckets().then((x: any) => console.log(x));

my-project-c1a44bf80be3.json (Download from GCP) exists and is the project level

Error:

event - compiled successfully
event - build page: /
wait  - compiling...
error - ./node_modules/@google-cloud/storage/build/src/file.js:24:0
Module not found: Can't resolve 'fs'
null
Could not find files for / in .next/build-manifest.json
event - compiled successfully

The same error appears when using googleapis. However, instead of ./node_modules/@google-cloud/storage/build/src/file.js:24:0 it's in the google-auth-library module that comes with the googleapis.

Added using yarn.

Timeout answered 22/9, 2020 at 13:11 Comment(0)
P
4

This usually happens when you import or reference firebase-admin in the client side, check your code for wrong imports where you might be calling

import * as firebase from "firebase-admin";

instead of

import firebase from "firebase";
Pituitary answered 7/3, 2022 at 19:8 Comment(2)
If anybody is initializing firebase twice on the same script (once for admin and once for frontend), then this might be the cause of the error since backend code is trying to get run on the frontend. Solution: initialize firebase admin in a different script than in front end, and do not call any exports on the backend script on the frontend. – Pave
exactly, you get my point – Pituitary
P
3

I faced the same problem but this guide was the solution in my case. As mentioned before, the problem is that the firebase-admin package is designed to run in a NodeJs environment and not on the client. Extending webpack.config.js or next.config.js with certain entries did not solve the problem for me.

I have noticed your are using NextJS. So the solution is to move the firebase-admin calls to the NextJS API which you can create within the /pages/api folder.

Here is a simple example to fetch user data from the client.

You need:

  • /src/lib/firebase.ts: firebase initialization
  • /src/pages/api/user.ts: NextJS API handler
  • /src/components/xyz.tsx: component on client, which calls the API
// /src/lib/firebase.ts
import admin from "firebase-admin";
import { cert } from "firebase-admin/app";
import certConfig from "./firebase-adminsdk-config.json"

admin.initializeApp({
  credential: cert(certConfig)
});
console.log("Firebase initialized.");


export default admin;

// /src/pages/api/user.ts
import admin from 'lib/firebase'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const firebase = admin.firestore()
  const collection = firebase.collection('users')

  // get any data from requests body
  const { user } = req.body

  // perform your firebase collection call
  const data = await collection.get(user.id)

  // return data to client
  res.status(200)
  res.json({ 
      success: true, 
      result: data 
  });
    
  return res
}

On the client side then you just have to perform a GET to your own API

// /src/components/xyz.tsx
...
  const onLogin = async (user) => {
    const response = await fetch(`/api/users`, {
      method: "GET",
      body: JSON.stringify({ user }),
    });

    // data => { success: boolean, result: any }
    const data = await response.json(); 
    return data;
  }
...
Phellem answered 16/12, 2022 at 8:1 Comment(2)
Oh thank you. I was struggling since yesterday on that. I understood a lot of thing with your sanwer! – Rabbit
Appreciate it πŸ™. Even have a look if you really want to use the firebase-admin SDK. There is a web SDK as well, which is designed to run on the client. – Phellem
R
1

Posting the solution provided in the comments for visibility.

In your webpack configuration, you can indicate that certain modules like fs should be stubbed out; at which point you should be able to run this library client-side. For example:

node: {
        // Some libraries import Node modules but don't use them in the browser.
        // Tell Webpack to provide empty mocks for them so importing them works.
        ...config.node,
        fs: 'empty',
        child_process : 'empty',
        net : 'empty',
        tls: 'empty',
      }
Rubadub answered 22/9, 2020 at 13:11 Comment(0)
T
0

Yup, had this issue while trying to use apis in firebase packages like firestore, @google-cloud/firestore, firebase-admin etc.

@Mo.W's answer above best explains it - the problem is that the firebase-admin package is designed to run in a NodeJs environment and not on the client. You can read his solution to moving it to pages/api

But, in my situation - I just specified that certain Node.js modules should be excluded when bundling the project for the browser environment in my package.json using browser configuration like this:

// package.json
{
    "name": "my-app-name",
    "dependencies": {
        "@google-cloud/firestore": "^6.7.0",
        "firebase": "^10.3.1",
        "firebase-admin": "^11.10.1",
        ...
    },
    "browser": {
        "fs": false,
        "os": false,
        "path": false,
        "child_process": false,
        "net": false,
        "tls": false
    }
}
Translucent answered 16/4 at 20:57 Comment(0)
S
-5

The scenario you are describing is now being handled by Google. Although there is no ETA, the issue is being prioritized.

Seineetmarne answered 23/9, 2020 at 20:58 Comment(4)
Is there more documentation on this or where I could follow the progress? – Timeout
I was able to find this link here: github.com/googleapis/google-api-nodejs-client/issues/2211 and some information you may need. Although you're using YARN, please look at googleapis/google-auth-library-nodejs#150 (comment) "Essentially, in your webpack configuration, you can indicate that certain modules like fs should be stubbed out; at which point you should be able to run this library client-side" – Seineetmarne
This is not an answer to the question, it's just a comment. – Pave
And here we are almost 4 years later. – Mammon

© 2022 - 2024 β€” McMap. All rights reserved.