skip to Main Content

I am currently developing a Java application that uses the Admin SDK to store and retrieve data from Google Firestore, but I also wanted to extend that use to Google Cloud Storage as well. When it comes to Firestore it is very clearly stated that access via Admin SDK ignores all Firebase Security rules and as a result, creating a Firebase App with my Service Account credentials is enough to grant access to all operations (If I’ve understood that correctly so far).

However when I try to download .png files that I’ve uploaded on Cloud Storage through Admin SDK I get the following error.

{
  "code" : 401,
  "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist).",
    "reason" : "required"
  } ],
  "message" : "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist)."
}

Here is the code that produces this error.

public void downloadImage() {
        
        firebase.initializeFirebase();

        Storage storage = StorageOptions.newBuilder()
                                  .setProjectId(MY_FIREBASE_ID).build()
                                  .getService();
        
        Blob blob = storage.get(BlobId.of(STORAGE_ID, OBJECT_NAME));
        blob.downloadTo(Paths.get(PATH));
    }

The roles of the Service Account include Admin, Storage Admin, Storage Object Viewer, Storage Object Admin and a few others. The Firebase App is initialized in the firebase.initializeFirebase() method with the credentials that I mentioned above.

I thought the Admin SDK gave complete access to a Firebase App with only the appropriate IAM Roles. Searching for this error, I encountered a few ways that authenticate and allow access correctly but they all used Firebase CLI. But how can I do the same using only the Admin SDK and Java code?

As stated above, I’ve tried giving any Storage related roles to my Service Account and generated a new JSON file with my credentials. I then used the code above to try and download an image from Cloud Storage but to no avail. I even went as far as to allow public access to anyone to the Cloud Storage. I went to the Cloud Storage rules and enabled read, write access without any conditions. But still no progress. I searched this specific question that I am asking right now but the results didn’t help me. Maybe I missed something, and in that case I’m sorry.

2

Answers


  1. Chosen as BEST ANSWER

    It seems like I have missed a critical point when modifying IAM permissions. What I did was navigate to Google Cloud Console>Cloud Storage>Buckets and then select the Bucket I wanted to download files from and change its scope. By default the value is going to be "Subject to object ACLs". It isn't the best practice but for my case I set it to public (available to anyone) by hitting the 3dots next to the Bucket I was interested in, then press ADD PRINCIPAL and selecting Storage Object Viewer as a role and allUsers as a Principal. From what I understand the authentication system you need to set-up, for access to Google Cloud Storage is ADC. It seems to be a form of authentication used alongside others authentication services. The thing with me is that I haven't set-up any authentication systems because I am working in the privileged environment of Admin SDK, so I was really confused since I was never denied access to Firestore before. I am pretty new to this so I might have misunderstood something, so I implore anyone interested, to read the link I shared above.


  2. The error says you are not using any credentials in the request. You need something like:

    export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

    To let the Storage service discover the credentials (outside of a Google cloud instance)

    And add the permissions to the bucket (or the project) with the minimal role your app needs and the principal as the service account email (or firebase credential email).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search