B4A Library [B4X] PocketBase - Open Source backend in 1 file


PocketBase was created to assist building self-contained applications that can run on a single server without requiring to install anything in addition.
The basic idea is that the common functionality like crud, auth, files upload, auto TLS, etc. are handled out of the box, allowing you to focus on the UI and your actual app business requirements.

Please note that PocketBase is neither a startup, nor a business. There is no paid team or company behind it. It is a personal open source project with intentionally limited scope and developed entirely on volunteer basis. There are no promises for maintenance and support beyond what is already available

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

After writing the Supabase client library for B4X, it's now time for a simpler self-hosting variant, for smaller projects that need a backend, but you don't want to write a complex API. Again, the goal is to get mentioned on the official Github repo with the B4X-Pocketbase library.

Roadmap
  • Authentification (Social Login)
    • Signin with Google
    • Signin with Apple
    • OTP
    • Sign In Anonymously
  • Database
    • Batch
    • Realtime
  • Storage
    • Download with progress
Examples and Tutorials
-Soon

PocketBase
Author: Alexander Stolte
Version: 1.00

  • Pocketbase
    • Events:
      • AuthStateChange (StateType As String)
      • RangeDownloadTracker (Tracker As PocketbaseRangeDownloadTracker)
    • Functions:
      • Initialize (URL As String)
        Initializes the object. You can add parameters to this method if needed.
      • InitializeEvents (Callback As Object, EventName As String)
    • Properties:
      • Auth As Pocketbase_Authentication [read only]
      • Database As Pocketbase_Database [read only]
      • LogEvents As Boolean
      • Storage As Pocketbase_Storage [read only]
      • URL As String [read only]
  • Pocketbase_Authentication
    • Functions:
      • ConfirmEmailChange (Token As String, Password As String) As ResumableSub
        Confirms the password reset with the verification token from the e-mail
        <code>
        Wait For (xPocketbase.Auth.ConfirmEmailChange("xxx","Test123!")) Complete (Response As PocketbaseError)
        If Response.Success Then
        Log("E-Mail change successfully")
        Else
        Log("Error: " & Response.ErrorMessage)
        End If
        </code>
      • ConfirmPasswordReset (Token As String, NewPassword As String, NewPasswordConfirm As String) As ResumableSub
        Confirms the password reset with the verification token from the e-mail
        <code>
        Wait For (xPocketbase.Auth.ConfirmPasswordReset("xxx","Test123!","Test123!")) Complete (Response As PocketbaseError)
        If Response.Success Then
        Log("Password change successfully")
        Else
        Log("Error: " & Response.ErrorMessage)
        End If
        </code>
      • ConfirmVerification (VerificationToken As String) As ResumableSub
        Confirms the user account with the verification token from the e-mail
        <code>
        Wait For (xPocketbase.Auth.ConfirmVerification("xxx")) Complete (Success As PocketbaseError)
        If Success.Success Then
        Log("verification sucessfull")
        Else
        Log("Error: " & Success.ErrorMessage)
        End If
        </code>
      • DeleteUser As ResumableSub
        Delete a single users record
        <code>Wait For (xPocketbase.Auth.DeleteUser) Complete (Success As PocketbaseError)</code>
      • GetAccessToken As ResumableSub
      • GetUser As ResumableSub
        Gets the user object
        <code>Wait For (xPocketbase.Auth.GetUser) Complete (User As PocketbaseUser)</code>
      • Initialize (ThisPocketbase As Pocketbase, EventName As String)
        Initializes the object. You can add parameters to this method if needed.
      • isUserLoggedIn As ResumableSub
        Checks if the user is logged in, renews the access token if it has expired
        <code>Wait For (xPocketbase.Auth.isUserLoggedIn) Complete (isLoggedIn As Boolean)</code>
      • Login_EmailPassword (Email As String, Password As String) As ResumableSub
        Authenticate with combination of email and password
        <code>
        Wait For (xPocketbase.Auth.LogIn_EmailPassword("test@example.com","Test123!")) Complete (User As PocketbaseUser)
        If User.Error.Success Then
        Log("successfully logged in with " & User.Email)
        Else
        Log("Error: " & User.Error.ErrorMessage)
        End If
        </code>
      • Logout As ResumableSub
        User tokens and infos are removed from the device
      • RefreshToken As ResumableSub
      • RequestEmailChange (NewEmail As String) As ResumableSub
        Sends users email change request
        On successful email change all previously issued auth tokens for the specific record will be automatically invalidated
        <code>
        Wait For (xPocketbase.Auth.RequestEmailChange("test@example.com")) Complete (Success As PocketbaseError)
        If Success.Success Then
        Log("E-Mail change request sent")
        Else
        Log("Error: " & Success.ErrorMessage)
        End If
        </code>
      • RequestPasswordReset (Email As String) As ResumableSub
        Sends users password reset email request
        On successful password reset all previously issued auth tokens for the specific record will be automatically invalidated
        <code>
        wait for (xPocketbase.Auth.PasswordRecovery("test@example.com")) Complete (Response As PocketbaseError)
        If Response.Success Then
        Log("Recovery email sent successfully")
        Else
        Log("Error: " & Response.ErrorMessage)
        End If
        </code>
      • RequestVerification (Email As String) As ResumableSub
        Sends users account verification request
        <code>
        Wait For (xPocketbase.Auth.RequestVerification("test@example.com")) Complete (Success As PocketbaseError)
        If Success.Success Then
        Log("verification code send to email")
        Else
        Log("Error: " & Success.ErrorMessage)
        End If
        </code>
      • SaveToken
      • SignUp (Email As String, Password As String, PasswordConfirm As String, Options As Map) As ResumableSub
        Allow your users to sign up and create a new account.
        Options - Optional fields
        A full list of values you find in the dashboard in the “API Preview” in the “users” collection
        <code>
        Wait For (xPocketbase.Auth.SignUp("test@example.com","Test123!","Test123!",Null)) Complete (NewUser As PocketbaseUser)
        If NewUser.Error.Success Then
        Log("successfully registered with " & NewUser.Email)
        Else
        Log("Error: " & NewUser.Error.ErrorMessage)
        End If
        </code>
      • UpdateUser (Options As Map) As ResumableSub
        Update a single users record
        A full list of values you find in the dashboard in the “API Preview” in the “users” collection
        <code>Wait For (xPocketbase.Auth.UpdateUser(CreateMap("name":"Test Name"))) Complete (Success As PocketbaseError)</code>
    • Properties:
      • TokenInformations As PocketbaseTokenInformations [read only]
      • UserCollectionName As String
        Change it only if you change the default "users" table name
  • Pocketbase_Database
    • Functions:
      • DeleteData As Pocketbase_DatabaseDelete
        Delete a single collection record
        <code>Wait For (xPocketbase.Database.DeleteData.Collection("dt_Task").Execute("43r7071wtp30l5h")) Complete (Result As PocketbaseError)</code>
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
      • InsertData As Pocketbase_DatabaseInsert
        <code>
        Dim Insert As Pocketbase_DatabaseInsert = xPocketbase.Database.InsertData.Collection("dt_Task")
        Insert.Parameter_Fields("Task_Name,Task_CompletedAt")
        Dim InsertMap As Map = CreateMap("Task_UserId":xPocketbase.Auth.TokenInformations.Id,"Task_Name":"Task 01","Task_CompletedAt"ocketbase_Functions.GetISO8601UTC(DateTime.Now))
        Wait For (Insert.Insert(InsertMap).Execute) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)
        </code>
      • PrintTable (Table As PocketbaseDatabaseResult)
      • SelectData As Pocketbase_DatabaseSelect
        <code>
        Wait For (xPocketbase.Database.SelectData.Collection("dt_Task").GetList(0,2,"")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)
        </code>
      • UpdateData As Pocketbase_DatabaseUpdate
        <code>
        Dim UpdateRecord As Pocketbase_DatabaseUpdate = xPocketbase.Database.UpdateData.Collection("dt_Task")
        UpdateRecord.Parameter_Fields("Task_Name,Task_CompletedAt")
        UpdateRecord.Update(CreateMap("Task_Name":"Task 02"))
        Wait For (UpdateRecord.Execute("77avq8zn44ck37m")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)
        </code>
  • Pocketbase_DatabaseDelete
    • Functions:
      • Collection (TableName As String) As Pocketbase_DatabaseDelete
      • Execute (RecordId As String) As ResumableSub
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
  • Pocketbase_DatabaseInsert
    • Functions:
      • Collection (TableName As String) As Pocketbase_DatabaseInsert
      • Execute As ResumableSub
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
      • Insert (ColumnValue As Map) As Pocketbase_DatabaseInsert
        Insert one row
        <code>Dim InsertMap As Map = CreateMap("Tasks_Name":"Task 01","Tasks_Checked":True,"Tasks_CreatedAt"ateUtils.TicksToString(DateTime.Now))</code>
      • Parameter_Expand (Expand As String) As Pocketbase_DatabaseInsert
        Auto expand record relations.
      • Parameter_Fields (Fields As String) As Pocketbase_DatabaseInsert
        Comma separated string of the fields to return in the JSON response (by default returns all fields).
        <code>CustomQuery.Parameter_Fields("Task_Name,Task_CompletedAt")</code>
      • Parameter_Files (Files As List)
  • Pocketbase_DatabaseSelect
    • Functions:
      • Collection (TableName As String) As Pocketbase_DatabaseSelect
      • GetCustom
        Create your own query with all available filters
        Use the "Parameter_" properties
        <code>
        Dim CustomQuery As Pocketbase_DatabaseSelect = xPocketbase.Database.SelectData.Collection("dt_Task")
        CustomQuery.Parameter_Page(0)
        CustomQuery.Parameter_PerPage(2)
        CustomQuery.Parameter_Fields("Task_Name,Task_CompletedAt")
        CustomQuery.Parameter_Sort("-Task_Name") 'DESC
        Wait For (CustomQuery.GetCustom) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)</code>
      • GetFirstListItem (Filter As String, Expand As String) As ResumableSub
        Returns the first found list item by the specified filter.
        <code> Wait For (xPocketbase.Database.SelectData.Collection("dt_Task").GetFirstListItem("","")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)</code>
      • GetFullList (Sort As String) As ResumableSub
        Returns a list with all items batch fetched at once.
        <code Wait For (xPocketbase.Database.SelectData.Collection("dt_Task").GetFullList("-Task_Name")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)</code>
      • GetList (Page As Int, PerPage As Int, Filter As String) As ResumableSub
        Returns paginated items list.
        <code>
        Wait For (xPocketbase.Database.SelectData.Collection("dt_Task").GetList(0,2,"")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)</code>
      • GetOne (RecordID As String) As ResumableSub
        Returns single item by its ID.
        <code> Wait For (xPocketbase.Database.SelectData.Collection("dt_Task").GetOne("77avq8zn44ck37m")) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)</code>
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
      • Parameter_Expand (Expand As String) As Pocketbase_DatabaseSelect
        Only for GetCustom
        Auto expand record relations.
      • Parameter_Fields (Fields As String) As Pocketbase_DatabaseSelect
        Only for GetCustom
        Comma separated string of the fields to return in the JSON response (by default returns all fields).
        <code>CustomQuery.Parameter_Fields("Task_Name,Task_CompletedAt")</code>
      • Parameter_Filter (Filter As String) As Pocketbase_DatabaseSelect
        Only for GetCustom
        Filter the returned records.
        Single filter:
        <code>CustomQuery.Parameter_Filter("Task_Name='Task 05'")</code>
        Multiple filter:
        <code>CustomQuery.Parameter_Filter("Task_Name='Task 05' && Task_UserId='86jzh49x5k2m387'")</code>
      • Parameter_Page (Page As Int) As Pocketbase_DatabaseSelect
        Only for GetCustom
        The page (aka. offset) of the paginated list (default to 1).
        <code>CustomQuery.Parameter_Page(0)</code>
      • Parameter_PerPage (perPage As Int) As Pocketbase_DatabaseSelect
        Only for GetCustom
        Specify the max returned records per page (default to 30).
        <code>CustomQuery.Parameter_PerPage(4)</CustomQuery.Parameter_PerPage(4)>
      • Parameter_SkipTotal (skipTotal As Boolean) As Pocketbase_DatabaseSelect
        Only for GetCustom
        If it is set the total counts query will be skipped and the response fields totalItems and totalPages will have -1 value.
        This could drastically speed up the search queries when the total counters are not needed or cursor based pagination is used.
        For optimization purposes, it is set by default for the getFirstListItem() and getFullList() SDKs methods.
      • Parameter_Sort (Sort As String) As Pocketbase_DatabaseSelect
        Only for GetCustom
        Specify the records order attribute(s).
        Add - / + (default) in front of the attribute for DESC / ASC order.
        <code>CustomQuery.Parameter_Sort("-Task_Name") 'DESC</code>
  • Pocketbase_DatabaseUpdate
    • Functions:
      • Collection (TableName As String) As Pocketbase_DatabaseUpdate
      • Execute (RecordId As String) As ResumableSub
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
      • Parameter_Expand (Expand As String) As Pocketbase_DatabaseUpdate
        Auto expand record relations.
      • Parameter_Fields (Fields As String) As Pocketbase_DatabaseUpdate
        Comma separated string of the fields to return in the JSON response (by default returns all fields).
        <code>CustomQuery.Parameter_Fields("Task_Name,Task_CompletedAt")</code>
      • Parameter_Files (Files As List)
      • Update (ColumnValue As Map) As Pocketbase_DatabaseUpdate
  • Pocketbase_Functions
    • Functions:
      • BytesToImage (bytes As Byte) As B4XBitmap
      • ConvertFile2Binary (Dir As String, FileName As String) As Byte()
      • CreateMultipartFileData (Dir As String, FileName As String, KeyName As String, ContentType As String) As MultipartFileData
        If you leave ContentType empty then the content type itself is determined using the file extension
      • GetFileExt (FileName As String) As String
      • GetFilename (fullpath As String) As String
      • GetISO8601UTC (Ticks As Long) As String
        ISO8601UTC
      • GetMimeTypeByExtension (Extension As String) As String
      • ParseDateTime (DateString As String) As Long
  • Pocketbase_InternFunctions
    • Functions:
      • CreateDatabaseResult (JsonString As String) As PocketbaseDatabaseResult
      • GenerateResult (j As HttpJob) As Map
      • GetJWTPayload (Token As String) As Map
      • PatchMultipart (j As HttpJob, Link As String, NameValues As Map, Files As List)
      • SubExists2 (Target As Object, TargetSub As String, NumbersOfParameters As Int) As Boolean
    • Properties:
      • ErrorCode As Int
        code: 400
      • ErrorMap As Map
        reason: invalid
        domain: global
        message: EMAIL_NOT_FOUND
      • ErrorMessage As String
        message: EMAIL_NOT_FOUND
  • Pocketbase_Storage
    • Fields:
      • Tag As Object
    • Functions:
      • DownloadFile (CollectionName As String, RecordId As String, FileName As String) As ResumableSub
        <code>
        Wait For (xPocketbase.Storage.DownloadFile("dt_Task","s64f723suu7b1p4","test_76uuo6rx0u.jpg")) Complete (StorageFile As PocketbaseStorageFile)
        If StorageFile.Error.Success Then
        Log($"File ${"test.jpg"} successfully downloaded "$)
        ImageView1.SetBitmap(xPocketbase.Storage.BytesToImage(StorageFile.FileBody))
        Else
        Log("Error: " & StorageFile.Error.ErrorMessage)
        End If
        </code>
      • Initialize (ThisPocketbase As Pocketbase)
        Initializes the object. You can add parameters to this method if needed.
      • Parameter_Thumb (Thumb As String) As Pocketbase_Storage
        If your file field has the Thumb sizes option, you can get a thumb of the image file (currently limited to jpg, png, and partially gif – its first frame)
        The following thumb formats are currently supported:
        WxH (e.g. 100x300) - crop To WxH viewbox (from center)
        WxHt (e.g. 100x300t) - crop To WxH viewbox (from top)
        WxHb (e.g. 100x300b) - crop To WxH viewbox (from bottom)
        WxHf (e.g. 100x300f) - fit inside a WxH viewbox (without cropping)
        0xH (e.g. 0x300) - resize To H height preserving the aspect ratio
        Wx0 (e.g. 100x0) - resize To W width preserving the aspect ratio
        <code>
        Dim GetFile As Pocketbase_Storage = xPocketbase.Storage
        GetFile.Parameter_Thumb("100x300")
        Wait For (GetFile.DownloadFile("dt_Task","s64f723suu7b1p4","test_76uuo6rx0u.jpg")) Complete (StorageFile As PocketbaseStorageFile)
        </code>
      • UploadFile (CollectionName As String, RecordId As String, FileData As MultipartFileData) As ResumableSub
        Single file upload
        <code>
        Dim FileData As MultipartFileData
        FileData.Initialize
        FileData.Dir = File.DirAssets
        FileData.FileName = "test.jpg"
        FileData.KeyName = "Task_Image"
        FileData.ContentType = "image/png"
        Wait For (xPocketbase.Storage.UploadFile("dt_Task","s64f723suu7b1p4",FileData)) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)
        </code>
      • UploadFiles (CollectionName As String, RecordId As String, FileData As List) As ResumableSub
        If your file field supports uploading multiple files
        FileDate - List of MultipartFileData
        <code>
        Dim lst_Files As List : lst_Files.Initialize
        lst_Files.Add(Pocketbase_Functions.CreateMultipartFileData(File.DirAssets,"test.jpg","Task_Image",""))
        lst_Files.Add(Pocketbase_Functions.CreateMultipartFileData(File.DirAssets,"test2.jpg","Task_Image",""))
        Wait For (xPocketbase.Storage.UploadFiles("dt_Task","s64f723suu7b1p4",lst_Files)) Complete (DatabaseResult As PocketbaseDatabaseResult)
        xPocketbase.Database.PrintTable(DatabaseResult)
        </code>
Setup
1. Follow the
Introductions docs
B4X:
Public xPocketbase As Pocketbase
#If B4J
xPocketbase.Initialize("http://127.0.0.1:8090") 'Localhost -> B4J only  
#Else
xPocketbase.Initialize("http://192.168.188.142:8090") 'IP of your PC
#End If
xPocketbase.InitializeEvents(Me,"Pocketbase")
xPocketbase.LogEvents = True

Changelog
  • 1.00
    • Release
Have Fun


Please always create a new thread for questions and problems, thank you
 

Attachments

  • PocketBase.b4xlib
    21.4 KB · Views: 13
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Again, the goal is to get mentioned on the official Github repo with the B4X-Pocketbase library.
Congrats again, there is a Show & Tell link on Discussions, you need to create a post there

Also, there is Awesome PocketBase created by the creator of PocketHost (this is a Saas) where from a single account you have have multiple instances of pocketbase running, its currently in 20 or so countries. I love it and are using it. Perhaps create a pull request so that a link of your b4xlib is listed there. Others have,

I am currently using PocketBase on all client applications, easy, even to create a hook..
 

Alexander Stolte

Expert
Licensed User
Longtime User
Thanks for the links, I will try to get in there in due course
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…