I have an issue related to Firestore, Hosting, and Cloud functions. I deployed a Nextjs application using the just-released experimental web framework support. I'm using Nextjs's Image API, and as expected, the Firebase CLI creates a cloud function for the project. Everything works fine at the start, but when I try to open a page in the application that reads some data from Firestore, it redirects to an auth page, which is unexpected.
Even when I auth with my Google account (since that's the logged-in user to the application), it returns a forbidden error and logs me out.
When I go back and try again, it returns a different error (most likely because I was logged out automatically).
I tried doing some research, and some people suggested adding an allUsers principal permission to Cloud functions, but that didn't work (Error: Principals of type allUsers and allAuthenticatedUsers cannot be added to this resource), and that's even insecure permission. Only authenticated users should be able to read data from the page as already configured in my Firestore security rules. So it's unclear what I need to do since Firebase created the Cloud function automatically or if this is related to my security rules and cloud functions.
What could be wrong? Everything works fine in my existing deployment setup to Netlify (where Edge functions are created automatically using their Nextjs plugin). I'm only trying to test the new Firebase web framework hosting features. Please let me know if you'd need me to provide some more context or debug files to better help you help me.
Thank you!
The message “ App requesting permission to access your google account “ pops up if the function runs in any region other than us-central1.
Currently, Firebase Hosting does not support Cloud Functions in any other regions, Except us-central1.
You can refer to this StackOverflow thread.
Related
I would like to ask for the help of people familiar with Firebase functions. I am struggling with the problem that uploading the code via firebase cli fails. It was working a few days ago, I didn't change anything in the world, I mean through the configuration. And it gets stuck at a part where not even a code change was made. I have had this problem ever since the client set the editor role to the owner role. But in theory this shouldn't be a problem.
firebase deploy --debug returns this:
{"error":{"code":403,"message":"Unable to retrieve the repository metadata for projects/{projectname}/locations/us-central1/repositories/gcf-artifacts. Ensure that the Cloud Functions service account has 'artifactregistry.repositories.list' and 'artifactregistry.repositories.get' permissions. You can add the permissions by granting the role 'roles/artifactregistry.reader'.","status":"PERMISSION_DENIED"}}
I set it up but it still doesn't work. Maybe in the wrong place or I don't know. I only encountered similar problems on the net, but none of them helped. I do not know what to do. Artifactregistry api is also enabled.
firebase functions:log :
2022-11-09T22:15:55.891760Z E friendRequestNotification: {"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{"code":7,"message":"Unable to retrieve the repository metadata for projects/{projectname}/locations/us-central1/repositories/gcf-artifacts. Ensure that the Cloud Functions service account has 'artifactregistry.repositories.list' and 'artifactregistry.repositories.get' permissions. You can add the permissions by granting the role 'roles/artifactregistry.reader'."},"authenticationInfo":{"principalEmail":"{email}"},"requestMetadata":{"callerIp":"{ip}","callerSuppliedUserAgent":"FirebaseCLI/11.16.0,gzip(gfe),gzip(gfe)","requestAttributes":{"time":"2022-11-09T22:15:56.055987Z","auth":{}},"destinationAttributes":{}},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.CreateFunction","authorizationInfo":[{"resource":"projects/{projectname}/locations/us-central1/functions/friendRequestNotification","permission":"cloudfunctions.functions.create","granted":true,"authorizationLoggingOptions":{"permissionType":"ADMIN_WRITE"},"resourceAttributes":{}}],"resourceName":"projects/{projectname}/locations/us-central1/functions/friendRequestNotification","request":{"function":{"sourceUploadUrl":"https://storage.googleapis.com/uploads-760418412171.us-central1.cloudfunctions.appspot.com/6d1f7217-7899-484f-911c-1dbcb4512d8d.zip?GoogleAccessId=service-{}#gcf-admin-robot.iam.gserviceaccount.com&Expires={}","labels":{"deployment-tool":"cli-firebase","firebase-functions-hash":"{hash}"},"runtime":"nodejs16","dockerRegistry":"ARTIFACT_REGISTRY","entryPoint":"friendRequestNotification","name":"projects/{projectname}/locations/us-central1/functions/friendRequestNotification","eventTrigger":{"eventType":"providers/cloud.firestore/eventTypes/document.create","resource":"projects/{projectname}/databases/(default)/documents/users/{userId}/friends/{friendId}"}},"location":"projects/{projectname}/locations/us-central1","#type":"type.googleapis.com/google.cloud.functions.v1.CreateFunctionRequest"},"resourceLocation":{"currentLocations":["us-central1"]}}
I have already tried all options within the Google cloud iam&admin settings, but nothing.
Well, I solved the issue by updating my credit card. Basically, billing was disabled because my credit card was expired and all the permissions were disabled.
Try to enable the created artifacts for your project on Google Cloud Console
https://console.cloud.google.com/artifacts
I have a React.js application powered by a number of Firebase functions and real time database standing behind them. It has been working without any issue for the past 2-3 months and now I am getting a warning on the functions logs which says that:
#firebase/database: FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"Failed to parse access token response: Error: Server responded with status 404.\"."}
The way I initialize firebase from my React.js application looks like this:
I have double-checked everything standing behind process.env and it seems to be as expected. The website written in React.js in hosted under the Firebase hosting.
And this is how Firebase functions connect to Admin SDK:
I am not sure what would be the issue here. Nothing has changes in the code base from our side. Not sure if Firebase changed something internally that we need to consider.
What solved the issue for me was to go to the google cloud console (where Firebase functions are also available). Then I opened one of the failing cloud functions and I navigated to
My_Function_Name/Edit/RUNTIME, BUILD AND CONNECTIONS SETTINGS/RUNTIME SERVICE ACCOUNT/
And then I noticed there that for all of my functions it was selected App Engine Default Service Account instead of Firebase Admin SDK. I never explicitly set the runtime to this option. So, when I brought it back to Firebase Admin SDK the error was gone I was able to use the application once again.
This is a web page located on Firebase Hosting, served dynamically through a rewrite to a Cloud Function
When browsing to the url, I receive "Error: Forbidden
Your client does not have permission to get URL [/theURL] from this server.
Everything works as long as I have "allUsers" added as a Cloud Functions Invoker on the function via the GCP console. I have confirmed this with testing just throwing that one switch and getting two different results.
I am logged into my Chrome browser with the same Google account as the owner of the GCP project
I am logged in to my Firebase website (Firebase Authentication and Firestore roles management) using the same Google account, with a Firebase __session cookie and all.
This started when I upgraded my Node.js engine from 8 to 10 with the recent warnings from Google that they're dropping support for 8. (I am assuming, but have no real idea, that the version 8 runtime environment didn't have this feature?)
I wrote these Cloud Functions without any knowledge of GCP authentication, so I am relatively confident that my coding inside the Cloud Function is secure, but if there is another layer of security that I could/should be using, I'm all for it.
I will want this website to be publicly accessible, but I can granulate the functions to public vs. non-public if necessary. (Basically, I was writing them as all publicly accessible and internally authenticated/secured anyway.)
I'm not very knowledgeable at all about the GCP authentication requirements, so it's hard for me to pin this down to one central question, but here are some questions I know I don't know:
Should Firebase Hosting be added as a member to GCP's authentication groups, so that GCP only allows service of a Cloud Function to the rewrite requests? It seems that would be the most secure and straightforward method.
Why is GCP telling my I'm forbidden when I'm the owner of the whole doggone project? Does this have to do with Firebase Rewrite or maybe HTTP requests being anonymous? If so, then how does one authenticate for a Cloud Function anyway?
Sorry for the large scope of the question; any guidance in the right direction is much appreciated.
GCP allUsers is not related to Firebase Authentication. They deal with different sets of users. A function should have GCP allUsers invoker permission in order to allow access from web and mobile apps where users are signed in with Firebase Auth. GCP does not check the Firebase user - that is up to the function to do, if it wants, using the Firebase Admin SDK.
I have implemented Firebase Authentication in my app, using the Google Provider and the "https://www.googleapis.com/auth/drive.appdata" scope so my app can access its application folder within Google Drive
This part works fine and I retrieve the FireBaseUser once the authentication completes
What I now want to do is to access my app storage on Google Drive, but I don't know how to do this using the result of the current authentication
I tried to follow this: https://github.com/gsuitedevs/java-samples/blob/master/drive/quickstart/src/main/java/DriveQuickstart.java
But this doesn't work on Android.
The main issue is how to create the Credentials object
Do you have any idea on how to initialize a Drive.Builder instance so I can write/read to the app Google Drive folder?
Thanks
This cannot be done directly, because the Firebase & Google login are not the same, even when having logged in to Firebase with a Google account. On Android one meanwhile only has the "last logged in Google account" available for the user's Drive (the one on the device, which has nothing to do with Firebase Authentication, where Google may only be used as an "Authentication Provider").
So there are generally two options available to you:
Grant a GCP service-account access to Drive API and use Cloud Functions to access it.
Instead use Cloud Storage, which is within the Firebase eco-system and is similar to Drive.
I could also think of a combined solution approach, where users would use Cloud Storage (together with Firebase Authentication) and having a Cloud Function which uses a service-account, which eg. copies or moves uploaded files into a folder your Drive.
Concerning that (obviously server-side) Java example, the credentials.json clearly hints for a service account... and this is exactly where you can obtain this file from. However, for Android this is pretty useless - because it has major security implications, to package service-account credentials in an easy to de-compile package and distribute it on the WWW (to everybody). The Google Play Store likely would not permit you to publish or even upload that, because there are security checks in place. You could in best case only deploy that code as App Engine module, but not as an Android module.
Sorry for having destroyed your delusions and for not being able to provide a ready-made solution for 500 imaginary internet points, which pay nothing - but at least I can tell what is technically possible and what isn't - which effectively might save you lots of time, trying to accomplish the impossible.
Due to there still being no support for web client reads from locally-emulated firestore at the moment, my best option for some parts of development is to allow the local functions to modify the real Firestore (in a separate dev project).
I tried the "Admin SDK configuration snippet", but it doesn't work, the reason I suppose being the mocked firebase-admin.
Has anyone documented doing this properly?