RomainVialard / FirebaseApp

Google Apps Script binding for Firebase Realtime Database
Apache License 2.0
116 stars 30 forks source link

Error: We're sorry, a server error occurred. Please wait a bit and try again. (line 303, file "Code", project "FirebaseApp") #23

Open derrickrc opened 5 years ago

derrickrc commented 5 years ago

Hello,

I started getting this error last night on a script that had been triggering fine all day. I'm not sure what the issue is, can you please advise? Thanks.

Derrick

derrickrc commented 5 years ago

OK, it seems to be working on my personal gmail and not my gSuite, I must have hit some limit yesterday. What are the limits? When will this reset? Midnight has come and gone my time and it's still throwing the error. Thank you.

vn78dev commented 4 years ago

I started getting the same error today. Nothing really changed in the code or scopes, but Stackdriver log refers to the FirebaseApp library.

error1 log
derrickrc commented 4 years ago

I started getting the same error today. Nothing really changed in the code or scopes, but Stackdriver log refers to the FirebaseApp library.

error1 log

Is it possible you hit the Apps Scripts usage limit for urlfetch calls?

vn78dev commented 4 years ago

no way, I ran fetches sort of 2 or 3 times today..

vn78dev commented 4 years ago

see if this screenshot helps, looks like "line 234" refers to the FirebaseApp code, not mine:

image

derrickrc commented 4 years ago

It looks like that's the line for throwing a generic error, hence why we don't get more detail on the error. I just ran my code and it executed. I'd try running it on a different gmail account to confirm you didn't exhaust your quota. Good luck.

vn78dev commented 4 years ago

I checked all the quotas and limits, including script runtime limit etc - nothing suspicious there. I then created a small test function just knocking to a database and received the same error. I ran it under another user and that didn't help too :(

Test function:

function testFb () {
  var dbUrl = "https://test.firebaseio.com/";
  var dbToken = ScriptApp.getOAuthToken();
  var db = FirebaseApp.getDatabaseByUrl(dbUrl, dbToken);
  Logger.log(JSON.stringify(db));
  var data = db.getData("testKey");
  Logger.log(data);
}

For some reason, the function returned url and the token: {"base":{"url":"https://test.firebaseio.com/","secret":"ya29.ImyUB9.........d778bbE"}}

If this helps with any ideas what might be wrong, I'd appreciate your help very much.

vn78dev commented 4 years ago

Solved it. The library error was triggered by the pair "urlFetchWhitelist": ["https://www.example.com/"] in my manifest json. Once I removed it, requests became successful. I am not sure whether it's a library problem though.

affordablequalityhomes commented 4 years ago

I'm getting the same error, in FirebaseApp_._sendAllRequests

So as per the comment above, I tried:

function test() {
  var m = UrlFetchApp.fetch('http://www.microsoft.com');
}

and that gave me a different error:

Exception: Service invoked too many times for one day: urlfetch. at ...

The quota for urlfetch is 20,000 / day

marcomow commented 3 years ago

I was able to solve this making a copy of the original library and adding there into the manifest appsscript.json this line "oauthScopes": ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/firebase.database", "https://www.googleapis.com/auth/script.external_request"] .

I suggest @RomainVialard to add these scopes into the original library, this will have also the nice side-effect of non constraining the users of the library to manual update of the scopes.

vn78dev commented 3 years ago

I am getting this error again - now it looks like it's triggered by Firebase limits for the number/length of keys. My database has grown and I am trying to implement a sort of pagination - with little success though as getData returns all the keys for a given path. Have you considered introducing pagination or 'ranged' requests, @RomainVialard? Or maybe there is an easier solution for this?

RomainVialard commented 3 years ago

@vn78dev getData() supports optQueryParameters as a second parameter. https://github.com/RomainVialard/FirebaseApp#getdatapath-optqueryparameters

For pagination you can use parameters like limitToFirst & startAt https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-filtering

dginovker commented 2 years ago

I created a general purpose function based on Romain's answer above. This will solve your "server error occurred" if the problem is you're pulling too much data:

// Reads data from Firebase Database that is >50Mb
// Splits up the read calls based on data keys
function readBulkDataFromFirebase(url, split = 1, start = " ") {
  // log(`Debug: Searching for next ${split} from [${start}]`);
  let base = FirebaseApp.getDatabaseByUrl(url, env.token);
  let data = base.getData("", { orderBy: "$key", startAt: start, limitToFirst: split });

  if (!data) return null;

  // If we got more data, recursively call and add the data further down
  let nextStart = Object.keys(data).sort((a, b) => b - a)[0] + " "; // The last key we grabbed plus space " "
  return {...data, ...readBulkDataFromFirebase(url, split, nextStart)};
}

Basically it works by grabbing the first split children of an object, then the next split, etc etc. Data is sorted based on keys to get an order, and a space character is added to the last pulled key so the next key we pull is the one that comes after it. When calling the function, choose a value of split that guarantees the getData() call won't pull down more than 50Mb at a time (easy to test this, just pick a value like 100, if you still get the error reduce it).

If any single child is over 50Mb, this solution won't work and you'll have to do something else

rahulraghuwanshii commented 1 year ago

@dginovker the solution given by you runs endlessly and faces an execution time-out issue. Is there any solution?