Storage get_url() issue
Looks like there are a lot of 403 forbidden issues relates to Firebase storage and I think I've figured out a way to solve it:
- Make sure to store the response after using put() for uploading images or files
- You can check what keys are inside response, please note 'bucket' and 'downloadTokens' are important keys we are going to use in the next step
- The actual file url that get_url() should provide is https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{path_to_file}?alt=media&token={downloadTokens} Hightlight: I think current get_url() method cannot return url correctly for storage that needs auth to access. The current method return base url appended with idToken as file download url, which is wrong: the token used here should be downloadTokens instead.
The problem is that it is expecting a "Token" parameter. Insert None as the parameter to get_url and you should be fine.
In the future, this should be defaulted to None in Pyrebase
Kindly update this in Readme doc about get_url() Could save countless hours for someone else, wasted mine today :-(
@cjbara Inserting " None " its not getting the rite Download URL By inserting " none" I get : https://firebasestorage.googleapis.com/v0/b/****/o/python%2FOct-31-2017%2FImage-12-19-26.jpg?alt=media URL on Firebase for Download https://firebasestorage.googleapis.com/v0/b/*****/o/python%2FOct-31-2017%2FImage-12-19-26.jpg?alt=media&token=62e4e729-991a-41f1-abb9-ed8e53d65873
Any solution for this issue Thanks
Same here, how to get the token?
Me too, the same issue. The authentication token is not the one which should be a part of url
Does anyone know how this token forms?
@evaverne I think the problem here is that in building url process there is used auth_token instead of the one generated per each file which in my opinion should be get from server. But if you take a look at code of get_url() method you'll see there is just concatenation of configuration's values passed by user. There is no request to server to obtain token.
Here you go the get_url():
def get_url(self, token):
path = self.path
self.path = None
if path.startswith('/'):
path = path[1:]
if token:
return "{0}/o/{1}?alt=media&token={2}".format(self.storage_bucket, quote(path, safe=''), token)
return "{0}/o/{1}?alt=media".format(self.storage_bucket, quote(path, safe=''))
@wstejka Exactly, that's why I thought there is an option to find out what's going on the google side. Looking through js now, it seems there is a working function for this purpose.
@evaverne @wstejka did you guys find out the solution
Any luck on this?
nevermind: I figured it out
You can only get the downloadToken when and from the put function. Then you can store that in a variable and it's a JSON string. You access and pass the downloadTokens to the get url function
@xaiyeon Does the put function return the token? Could you please tell me how to get the token? I tried but the put function return None.
@Pod5GS Hey Pod, I'm not sure if I explain it, it would make sense... After you use the Put function you can assign it to a variable and then it actually saves the entire request into a JSON. Then you can access the object for it, specifically the downloadTokens, and you can store that into another variable and use it for the get_url token parameter. You can see my code here, it has comments, but this is for a project I head and own.
Go to line at 214 and read my comments from there. I hope it helps.
https://github.com/xaiyeon/wamain-proj/blob/master/wamain.py
This's not perfect solution. But, if you can give up read permission, you can do this.
Change the storage rule.
-basic rule- service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } }
-changed-
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read; allow write: if request.auth != null; } } }
and, just using function -> get_url(None)
storage.child("PHOTO_PATH").get_url(None) pass null as a token It worked for me
storage.child("PHOTO_PATH").get_url(None) pass null as a token It worked for me
Nice work but this will give you a url path which will be denied by google. so url is unusable.
You can avoid this issue by simply inserting 'None' as a parameter
You can pass the Parameter as "None" it Will Work for You
The current get_url method takes the bearer token as a token URL parameter which in fact is a different token, named access token or download token.
I have changed the method so that it works for all types of firebase storage rules by retrieving the access token first and passing it into the URL.
Before the get_url() method returns

After changes, it returns the URL with the correct token

I have opened a pull request for this fix. https://github.com/thisbejim/Pyrebase/pull/417#issue-1198939874
@hereisamara but how do I apply this solution?
For now, you can use it like this. First, retrieve the access token of the file in firebase storage and pass it into the get_url method.
You will need requests module. https://pypi.org/project/requests/

add None in get_url example: nike = storage.child("sepatu/nike1.jpeg").get_url(None)