Android Question Howto get a Firebase Storage's file public https:-URL?

fredo

Well-Known Member
Licensed User
Longtime User
@Erel 's Firebase Storage library is easy to setup and easy to use.
A Testproject is working well with and without authentication.
The "UploadCompleted" event delivers the Serverpath (1), which is fine so far and can be used with the gs:\\ protocol (2) by authenticated users.

In order to download the file from unauthenticated users a https:\\-URL (3) is needed.

So, this is the question:
How to get the Firebase Storage public https://-URL from the storage object? (4)

I could find this valuable information in SO here but was not able to get a grip on a solution:

The Firebase documentation gives some explanations, but in a language with "curly brackets" ...

I saw this post from @alwaysbusy 's wonderful "ABMaterial"-world, but it's B4J.




___
Please ignore the attached file. I can't remove it since the normal "Edit"-"More options" produces a "ERR_BLOCKED_BY_XSS_AUDITOR"
 

Attachments

  • 12-08-_2017_17-05-32.png
    35.2 KB · Views: 524
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Note that it is better to post code as text with code tags.

In order to download the file from unauthenticated users a https:\\-URL (3) is needed.
That's not correct. The https link allows users to download it without the firebase SDK.

Do you want to allow users to download the resource outside of your app?
 
Upvote 0

fredo

Well-Known Member
Licensed User
Longtime User
...without the firebase SDK.
I wasn't aware of that. Thank you.

...allow users to download the resource outside of your app?
Yes.
Some files (small datapacks in json format) shall be shared with trusted individuals via an ungeuessable URL outside our app.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here:
B4X:
Sub btnDownloadPublic_Click
   Wait For (GetDownloadUrl("/public/Untitled.png")) Complete (Url As String)
   If Url <> "" Then
     Log(Url)
   End If
End Sub

Sub GetDownloadUrl(ServerPath As String) As ResumableSub
   Dim fs As JavaObject = Starter.storage
   fs = fs.GetField("fs")
   Dim ref As JavaObject = fs.RunMethod("getReferenceFromUrl", Array(Starter.bucket & ServerPath))
   Dim task As JavaObject = ref.RunMethod("getDownloadUrl", Null)
   Do While task.RunMethod("isComplete", Null) = False
     Sleep(100)
   Loop
   If task.RunMethod("isSuccessful", Null) Then
     Dim s As String = task.RunMethod("getResult", Null)
     Return s
   Else
     Log("Error")
     Return ""
   End If
End Sub
This code uses the new feature added in v7.30 that allows resumable subs to return values.
 
Upvote 0

fredo

Well-Known Member
Licensed User
Longtime User
Thank you Erel! The support from Anywhere Software is superb as always.

Since we wanted a "nontalking" URL I added an URL shortener inspired by Erel here.
Although I'm not sure if I used the new ResumableSub feature correct, it delivers the expected results.

B4X:
...
      wait for (GetDownloadUrl(ServerPath)) complete (strDownloadUrlHttps As String)
      If strDownloadUrlHttps.Length > 0 Then

          wait for(ShortenUrl(strDownloadUrlHttps)) complete (strUrlShort As String)
          Log( strUrlShort )

      End If
...

Sub ShortenUrl(url As String) As ResumableSub
    Dim j As HttpJob
    j.Initialize("shortenurl", Me)
    Dim jg As JSONGenerator
    jg.Initialize(CreateMap("longUrl": url))
    ' Google API key is awailable here --> https://console.developers.google.com/apis/api/urlshortener.googleapis.com/overview?project=yyyyyyyyyyyyyyyyyyyyyyyyyy
    '  (don't forget to ENABLE)
    j.PostBytes($"https://www.googleapis.com/urlshortener/v1/url?key=${Starter.apikey}"$, jg.ToString.GetBytes("UTF8"))
    j.GetRequest.SetContentType("application/json")
    wait for JobDone(job As HttpJob)
    Dim shortUrl As String = ""
    If job.JobName = "shortenurl" Then
        If job.Success Then
            Dim jp As JSONParser
            jp.Initialize(job.GetString)
            shortUrl = jp.NextObject.Get("id")
        Else
            Log("Error: " & job.ErrorMessage)
        End If
    End If
    job.Release
    Return shortUrl
End Sub

Info: The shortened URL is easy to unshort, so it's only a weak obfuscation measure
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The code is mostly correct. It can be improved with:

1. Don't set the job name.
2. Set the sender filter parameter when waiting for JobDone:

B4X:
Sub ShortenUrl(url As String) As ResumableSub
    Dim j As HttpJob
    j.Initialize("", Me)
    Dim jg As JSONGenerator
    jg.Initialize(CreateMap("longUrl": url))
    ' Google API key is awailable here --> https://console.developers.google.com/apis/api/urlshortener.googleapis.com/overview?project=yyyyyyyyyyyyyyyyyyyyyyyyyy
    '  (don't forget to ENABLE)
    j.PostBytes($"https://www.googleapis.com/urlshortener/v1/url?key=${Starter.apikey}"$, jg.ToString.GetBytes("UTF8"))
    j.GetRequest.SetContentType("application/json")
    wait for (j) JobDone(job As HttpJob)
    Dim shortUrl As String = ""
        If job.Success Then
            Dim jp As JSONParser
            jp.Initialize(job.GetString)
            shortUrl = jp.NextObject.Get("id")
        Else
            Log("Error: " & job.ErrorMessage)
        End If
    job.Release
    Return shortUrl
End Sub

There could be any number of concurrent HttpJob requests. By setting the sender filter parameter you make sure that only the one created locally will be intercepted by the relevant Wait For call.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…