firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

Firebase Emulator halted when uploading pdf to Storage "Error: An unexpected error has occurred"

Open isanecat opened this issue 2 years ago • 10 comments

I have a cloud function which works for creating a PDF triggered from firestore onCreate function. The function will store the PDF to Firebase storage after creation. The function is written in Node.js. Firebase emulator crashes with "Error: An unexpected error has occurred." when function triggered with Flutter code.

(Ubuntu 22.04)
Firebase version : 11.0.1 node version: v16.14.0 Browser: Chrome Firebase login completed with sudo privilege

Below one is storage.rules:

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

Below one is firestore.rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /Admins/{_adminID}/Package/{adminID_} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true && 
        resource.data.Admin_ID == request.auth.uid;
    }
    match /Admins/{AdminID}/Team/{UserID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true; 
    }
    match /Users/{UserID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true; 
    }
    match /TeamRequests/{RequestUserID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true; 
    }
    match /Admins/{AdminID}/Companies/{CompanyID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true;
    }
    match /Admins/{AdminID}/Companies/{CompanyID}/Imports/{ImportID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true;
    }
    match /Admins/{AdminID}/Companies/{CompanyID}/Imports/{ImportID}/Transaction/{TransactionID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true;
    }
    match /Admins/{AdminID}/Companies/{CompanyID}/Imports/{ImportID}/Transactions/{TransactionID}/Storage_Files/{StorageFileID} {
      allow read, write: if 
        request.auth != null && 
        request.auth.token.email_verified == true;
    }
  }
}

Below one is firebase functions :

const functions = require("firebase-functions");
const PdfKit = require("pdfkit");
const admin = require("firebase-admin");
const db = admin.firestore();


exports.createIremPdf = functions.firestore.document(
    "Admins/{adminID}/Companies/{companyID}/Imports/{impID}/Transactions/{tranzID}")
    .onCreate(async (data, context) => {
     
      const snapshot = await db.
          collection("Admins").doc(context.params.adminID).
          collection("Companies").doc(context.params.companyID).
          collection("Imports").doc(context.params.impID).
          collection("Transactions").doc(context.params.tranzID).
          collection("Storage_Files").get();
      let refCounter = snapshot.size;
      refCounter++; 
      const dosyaAdi = data.data().Transaction_ID + "-" + refCounter.
          toString();
      dosyaAdi;

        const pdfDoc = new PdfKit();

      const file = await admin
          .storage()
          .bucket()
          .file(("Admins/").concat(context.params.adminID).
              concat("/Companies/").concat(context.params.companyID).
              concat("/Imports/").concat(context.params.impID).
              concat("/Transactions/").concat(context.params.tranzID).
              concat("/Storage_Files/").concat("dosyaAdi").concat(".pdf"));

      await new Promise((resolve, reject) => {
        const writeStream = file.createWriteStream({
          resumable: false,
          contentType: "application/pdf",
        });

        writeStream.on("finish", () => resolve());
        writeStream.on("error", (e) => reject(e));
        pdfDoc.pipe(writeStream);

        pdfDoc
            .fontSize(24)
            .text(`${data.data().I_Rem_Beneficiary_Bank}`)
            .fontSize(16)
            .moveDown(2)
            .text("This is your receipt!");
        pdfDoc.end();
      });

      const metadata = await file.getMetadata().then((data)=>{
        return data[0];
      });

      const currentTime = admin.firestore.FieldValue.serverTimestamp();
      await db
          .collection("Admins")
          .doc(context.params.adminID)
          .collection("Companies")
          .doc(context.params.companyID)
          .collection("Imports")
          .doc(context.params.impID)
          .collection("Transactions")
          .doc(context.params.tranzID)
          .collection("Storage_Files")
          .add({
            "File_Name": "dosyaAdi.pdf",
            "Description": "Bank Instruction",
            "Creator": data.data().Creator,
            "Upload_Time": currentTime,
            "File_Size": parseInt(metadata.size),
            "File_Path": metadata.name,
          });

    });

isanecat avatar May 25 '22 20:05 isanecat

@isanecat Would you mind attaching the storage-debug.log and functions-debug.log after the crash?

yuchenshi avatar May 25 '22 21:05 yuchenshi

Emulator hasn't created any file such as storage-debug.log and functions-debug.log after the crash. There is only firestore-debug.log as follows:

May 25, 2022 9:50:11 PM com.google.cloud.datastore.emulator.firestore.websocket.WebSocketServer start
INFO: Started WebSocket server on ws://localhost:35389
API endpoint: http://localhost:8080
If you are using a library that supports the FIRESTORE_EMULATOR_HOST environment variable, run:

   export FIRESTORE_EMULATOR_HOST=localhost:8080

Dev App Server is now running.

May 25, 2022 9:50:25 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 9:50:25 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected HTTP/2 connection.
May 25, 2022 9:50:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 9:50:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 9:50:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 9:50:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 9:50:26 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:04 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:05 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:05 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:06 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:06 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:06 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:11 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:11 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:11 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:11 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:11 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:12 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:13 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:15 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:15 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:34 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:34 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:34 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:34 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected non-HTTP/2 connection.
May 25, 2022 10:01:35 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
INFO: Detected HTTP/2 connection.

isanecat avatar May 26 '22 04:05 isanecat

There is no Emulator crash and file created as requested when I change below code for storage path as follows:

      const file = await admin
          .storage()
          .bucket()
          .file(("Admins/").concat(context.params.adminID).
              concat("/Companies/").concat(context.params.companyID).
              concat("/Imports/").concat(context.params.impID).
              concat("/Transactions/").concat(context.params.tranzID).
              concat("/").concat("dosyaAdi").concat(".pdf"));

Its is strange that removing "Storage_Files/" make difference despite no specific path mentioned on storage.rules but I need this kind of sub folders.

isanecat avatar May 26 '22 05:05 isanecat

Having similar issue. The problem arises when I tried to putFile to storage but no problem when accessing file. The emulator will abruptly stop without giving any meaningful info.

phath9 avatar May 31 '22 14:05 phath9

It seems to be related to storage rules. From my testing, only allow read, write: if true; works. Any other complex rules will break the Emulator.

Maybe related to https://github.com/firebase/firebase-tools/issues/3550. However I'm using latest (11.0.1) version of Firebase Tools but it still crashes.

Not sure if this line causes the crash, from firebase-debug.log

[debug] [2022-05-31T17:26:01.634Z] Error: ENOENT: no such file or directory, open 'C:\Users<user>\AppData\Local\Temp\firebase\storage\blobs<project>.appspot.com_o_users%252Ftest%252Fmedia%252Ftest.txt' at openSync (node:fs:585:3) at Persistence.readBytes (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\lib\emulator\storage\persistence.js:37:36) at StorageLayer.uploadObject (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\lib\emulator\storage\files.js:157:52) at handleUpload (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\lib\emulator\storage\apis\firebase.js:302:53) at handleObjectPostRequest (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\lib\emulator\storage\apis\firebase.js:387:16) at Layer.handle [as handle_request] (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) at C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:281:22 at param (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:354:14) at param (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:365:14) at param (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:365:14) at Function.process_params (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:410:3) at next (C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\node_modules\express\lib\router\index.js:275:10) at C:\Users<user>\AppData\Roaming\nvm\v16.15.0\node_modules\firebase-tools\lib\emulator\storage\apis\firebase.js:68:9 [error] [error] Error: An unexpected error has occurred.

phath9 avatar May 31 '22 15:05 phath9

This may be related to https://github.com/firebase/firebase-tools/issues/4470 and long file paths.

My storage rules are already set to allow read, write: if true; but I am still encountering this error.

alexstanbury avatar Jun 27 '22 10:06 alexstanbury

I have been experiencing this exact same issue when using Firebase Storage. Any temporary solutions or fixes for this?

Been using Flutter and whenever uploading a JPG image to Storage, the entire emulator crashes predominantly. The error is vague and no logs can be found to get a reason as to why this is happening. I am unable to upload files to storage on my emulator, however, the production server works fine, which defeats the whole point of the emulator, testing locally.

ZiyadF296 avatar Jul 18 '22 15:07 ZiyadF296

This may be related to #4470 and long file paths.

My storage rules are already set to allow read, write: if true; but I am still encountering this error.

I've tested with short file names, mine still crashed if rules are complex. I guess there are multiple causes to this but we can't distinguish easily because no debug info available.

phath9 avatar Jul 24 '22 17:07 phath9

Likely related to internal bug, b/234835425

tonyjhuang avatar Jul 28 '22 18:07 tonyjhuang

Can folks confirm that this bug is only applicable to Flutter usages?

tonyjhuang avatar Jul 28 '22 18:07 tonyjhuang

Closing due to inactivity

tonyjhuang avatar Oct 07 '22 18:10 tonyjhuang