Pyrebase icon indicating copy to clipboard operation
Pyrebase copied to clipboard

Storage get_url() issue

Open ininex opened this issue 8 years ago • 21 comments

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:

  1. Make sure to store the response after using put() for uploading images or files
  2. 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
  3. 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.

ininex avatar Feb 13 '17 15:02 ininex

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

cjbara avatar Mar 05 '17 23:03 cjbara

Kindly update this in Readme doc about get_url() Could save countless hours for someone else, wasted mine today :-(

lohriialo avatar Aug 30 '17 12:08 lohriialo

@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

ubihacks avatar Nov 01 '17 07:11 ubihacks

Same here, how to get the token?

evaverne avatar Nov 01 '17 14:11 evaverne

Me too, the same issue. The authentication token is not the one which should be a part of url

wstejka avatar Nov 01 '17 16:11 wstejka

Does anyone know how this token forms?

evaverne avatar Nov 01 '17 16:11 evaverne

@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 avatar Nov 01 '17 16:11 wstejka

@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 avatar Nov 01 '17 16:11 evaverne

@evaverne @wstejka did you guys find out the solution

ubihacks avatar Nov 03 '17 13:11 ubihacks

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 avatar Nov 27 '17 22:11 xaiyeon

@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 avatar Dec 02 '17 22:12 Pod5GS

@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

xaiyeon avatar Dec 02 '17 23:12 xaiyeon

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)

ngost avatar Nov 22 '18 06:11 ngost

storage.child("PHOTO_PATH").get_url(None) pass null as a token It worked for me

asgaraliyev avatar Oct 22 '20 21:10 asgaraliyev

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.

successanil avatar Nov 24 '20 03:11 successanil

You can avoid this issue by simply inserting 'None' as a parameter

RiviWickramarachchi avatar Mar 05 '21 10:03 RiviWickramarachchi

You can pass the Parameter as "None" it Will Work for You

bugzzbunny007 avatar Dec 20 '21 06:12 bugzzbunny007

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 image

After changes, it returns the URL with the correct token image

I have opened a pull request for this fix. https://github.com/thisbejim/Pyrebase/pull/417#issue-1198939874

hereisamara avatar Apr 10 '22 08:04 hereisamara

@hereisamara but how do I apply this solution?

MajdMsallati avatar May 28 '22 07:05 MajdMsallati

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/

image

hereisamara avatar Jun 01 '22 19:06 hereisamara

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

wanazmi69 avatar Jul 23 '22 13:07 wanazmi69