B4A Library Firebase Realtimedatabase

Discussion in 'Additional libraries, classes and official updates' started by DonManfred, Aug 6, 2016.

  1. DonManfred

    DonManfred Expert Licensed User

    This is is a wrap for the Firebase RealtimeDatabase.

    Please click here to donate for my work to write the wrapper (You can donate any amount you want :) but the minimum donation should be $10 for this Library)
    [​IMG]

    Please note that this version is not known as stable but - for me - it seems to be working like i expect it
    I don´t know if everything works but so far i tested it today it works :D

    Please note that the wrap for the Query object is NOT finished. Also others may be incomplete...

    To prepare you app you need to use B4A 6+ and you need to follow the Firebase integration and download the json from the firebaseonsole!

    If you have successfully connected your appwith firebase the library will know the Database used.

    What you need to do is to get a reference to a specific tree in the database-tree



    FirebaseRealtimeDatabase

    Author: DonManfred
    Version: 2.82
    • DataSnapshot
      • Functions:
        • exists As Boolean
        • getChild (child As String) As DataSnapshot
        • hasChild (paramString As String) As Boolean
        • hasChildren As Boolean
        • Initialize (paramDataSnapshot As com.google.firebase.database.DataSnapshot)
        • Value2Map (paramObject As Object) As Object
      • Properties:
        • Children As List [read only]
        • ChildrenCount As Long [read only]
        • DBRef As DatabaseReference [read only]
        • Key As String [read only]
        • Priority As Object [read only]
        • Value As Object [read only]
        • Value2 As Object [read only]
    • DatabaseError
      • Fields:
        • DATA_STALE As Int
        • DISCONNECTED As Int
        • EXPIRED_TOKEN As Int
        • INVALID_TOKEN As Int
        • MAX_RETRIES As Int
        • NETWORK_ERROR As Int
        • OPERATION_FAILED As Int
        • OVERRIDDEN_BY_SET As Int
        • PERMISSION_DENIED As Int
        • UNAVAILABLE As Int
        • UNKNOWN_ERROR As Int
        • USER_CODE_EXCEPTION As Int
        • WRITE_CANCELED As Int
      • Functions:
        • Initialize (paramDatabaseError As com.google.firebase.database.DatabaseError)
        • IsInitialized As Boolean
      • Properties:
        • Code As Int [read only]
        • Details As String [read only]
        • Message As String [read only]
    • DatabaseReference
      • Events:
        • onCancelled (errorCode As Int, errorMessage As String, error As Object, tag As Object)
        • onChildAdded (Snapshot As Object, child As String, tag As Object)
        • onChildChanged (Snapshot As Object, child As String, tag As Object)
        • onChildMoved (Snapshot As Object, child As String, tag As Object)
        • onChildRemoved (Snapshot As Object, tag As Object)
        • onComplete (resultCode As Int, resultMessage As String, result As Object)
        • onDataChange (Snapshot As Object, tag As Object)
      • Functions:
        • addChildEventListener
          Add a ChildEvent-Listener
          If a change occur on a Child then
          there are some Events which can raise.
          onChildAdded holding a DatabaseSnapshot
          of the added Child.
          onChildChanged holding a DatabaseSnapshot
          of the changed child.
          onChildMoved holding a DatabaseSnapshot
          of the moved child.
          onChildRemoved holding a DatabaseSnapshot
          of the removed child.
        • addListenerForSingleValueEvent
          Add a listener for ANY change.
          If any changes occur then the
          Event onDataChange is raised holding
          a DatabaseSnapshot in total.
        • addValueEventListener
        • Child (child As String) As DatabaseReference
        • equalTo (reference As String) As FBQuery
        • equalTo2 (child As String, reference As String) As FBQuery
        • goOffline
        • goOnline
        • Initialize (EventName As String, parref As com.google.firebase.database.DatabaseReference, tag As Object)
        • IsInitialized As Boolean
        • keepSynced (sync As Boolean)
        • LimitToFirst (limit As Int) As FBQuery
        • LimitToLast (limit As Int) As FBQuery
        • onDisconnectCancel
        • onDisconnectRemove
        • onDisconnectSetValue (value As Map)
        • orderByChild (child As String) As FBQuery
        • orderByKey As FBQuery
        • orderByPriority As FBQuery
        • orderByValue As FBQuery
        • push As DatabaseReference
        • removeValue
        • setEventname (EventName As String, Tag As Object) As DatabaseReference
        • setValue (content As Map, child As String, EventName As String)
        • updateChildren (paramMap As Map)
      • Properties:
        • BA As BA [read only]
        • EventName As String [read only]
        • Key As String [read only]
        • Parent As DatabaseReference [read only]
        • Ref As DatabaseReference [read only]
        • Root As DatabaseReference [read only]
        • Tag As Object
    • DocumentSnapshot
      • Functions:
        • exists As Boolean
        • getChild (child As String) As DocumentSnapshot
        • hasChild (paramString As String) As Boolean
        • hasChildren As Boolean
        • Initialize (paramDataSnapshot As com.google.firebase.database.DataSnapshot)
        • IsInitialized As Boolean
        • setEventname (EventName As String, Tag As Object) As DocumentSnapshot
        • Value2Map (paramObject As Object) As Object
      • Properties:
        • Children As List [read only]
        • ChildrenCount As Long [read only]
        • EventName As String [read only]
        • Key As String [read only]
        • Priority As Object [read only]
        • Ref As DatabaseReference [read only]
        • Tag As Object
        • Value As Object [read only]
        • Value2 As Object [read only]
    • FBQuery
      • Events:
        • Snapshot (sign As Object)
      • Functions:
        • addChildEventListener
        • addListenerForSingleValueEvent
        • addValueEventListener
        • Initialize (EventName As String, query As com.google.firebase.database.Query)
        • limitToFirst (limit As Int) As FBQuery
        • limitToLast (limit As Int) As FBQuery
        • orderByChild (path As String) As FBQuery
        • startAt (arg0 As String, arg1 As String) As FBQuery
      • Properties:
        • QueryObj As Object [read only]
        • Tag As Object
    • FireLayout
      • Events:
        • onFireLayoutChildClicked (view As Object)
        • onFireLayoutChildLongClicked (view As Object)
      • Functions:
        • BringToFront
        • DesignerCreateView (base As Panel, lw As Label, props As Map)
        • init
        • Initialize (EventName As String)
        • Invalidate
        • Invalidate2 (arg0 As android.graphics.Rect)
        • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
        • IsInitialized As Boolean
        • RemoveView
        • RequestFocus As Boolean
        • SendToBack
        • SetBackgroundImage (arg0 As android.graphics.Bitmap) As BitmapDrawable
        • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
        • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
        • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
        • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
      • Properties:
        • Background As android.graphics.drawable.Drawable
        • Color As Int [write only]
        • Enabled As Boolean
        • Height As Int
        • Id As Int [read only]
        • Left As Int
        • Padding As Int()
        • Parent As Object [read only]
        • Tag As Object
        • Top As Int
        • Visible As Boolean
        • Width As Int
    • FirebaseDatabase
      • Functions:
        • getReference2 (path As String) As DatabaseReference
        • getReferencefromUrl (url As String) As DatabaseReference
        • goOffline
        • goOnline
        • Initialize (EventName As String)
        • orderByValue As FBQuery
        • purgeOutstandingWrites
        • Value2Map (value As Object) As Object
      • Properties:
        • LogLevel As com.google.firebase.database.Logger.Level [write only]
        • PersistenceEnabled As Boolean [write only]
        • Reference As DatabaseReference [read only]
    • GeoFire
      • Events:
        • onComplete (key As String, error As Databaseerror)
        • onDataChanged (datasnapshot As DataSnapshot, location As GeoLocation)
        • onDataEntered (datasnapshot As DataSnapshot, location As GeoLocation)
        • onDataExited (datasnapshot As DataSnapshot)
        • onDataMoved (datasnapshot As DataSnapshot, location As GeoLocation)
        • onGeoQueryError (error As Databaseerror)
        • onGeoQueryReady()
        • onKexExited (key As String)
        • onKeyEntered (key As String, location As GeoLocation)
        • onKeyMoved (key As String, location As GeoLocation)
      • Functions:
        • addGeoQueryDataEventListener
        • addGeoQueryEventListener
        • Initialize (EventName As String, lat As Double, lon As Double, radius As Double)
        • setLocation (key As String, location As com.firebase.geofire.GeoLocation)
        • setQueryCenter (center As com.firebase.geofire.GeoLocation, radius As Double)
      • Properties:
        • Center As com.firebase.geofire.GeoLocation
        • Radius As Double
    • GeoLocation
      • Functions:
        • Initialize (lat As Double, lon As Double)
        • IsInitialized As Boolean
      • Properties:
        • latitude As Double [read only]
        • longitude As Double [read only]

    Code:
    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.
        Dim realtime As FirebaseDatabase
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        'Activity.LoadLayout("Layout1")
        realtime.Initialize("Realtime")
        realtime.PersistenceEnabled = 
    True
        realtime.goOnline

        
    Dim myref As DatabaseReference
        myref.Initialize(
    "Reference",realtime.getReference2(""),"root")
    End Sub
    The code will get a reference to the root database... You can for sure get a ref to any "subfolder" inside the db.

    Code:
    mymessages.Initialize("Chat",realtime.getReference2("users/"&Starter.phone.GetSettings("android_id")&"/Messages"),"users/"&Starter.phone.GetSettings("android_id")&"/Messages")
    Please click here to donate for my work to write the wrapper (You can donate any amount you want :) but the minimum donation should be $10+ for this Library)
    [​IMG]

    Setup:
    Download the 3rdparty jars from --->DOWNLOAD HERE<---. Due to their size i needed to place it on my Dropbox. Copy the content to your additional libs folder.

    Download the most up to date libraryfiles (FirebaseRealtimeDatabaseVx.xx.zip) and put the content to your additional libs folder.
     

    Attached Files:

    Last edited: Jan 4, 2019
  2. fredo

    fredo Active Member Licensed User

    -....- -....- -....- / - .... .. ... / .. ... / ..-. --- .-. / - .... . / --- .-.. -.. / .-.. .. -... .-. .- .-. -.-- / ...- .---- .-.-.- -..- / -....- -....- -....-


    Great, I don't know what to say.
    The last days I tried to figure out a way to get a grip on this really important library and now this :cool:

    I will test it and give feedback here the next days.

    For your tests it might be helpful to have a fully working app with the Firebase Realtime Database to compare your development.

    For that I found the "Quickstart" pack in github here: https://github.com/firebase/quickstart-android

    Without any knowledge of JAVA functionality and the development process I was able to compile the Quickstart via Google's "Android Studio" and had it up in short time.

    Whoever is interested might have a look here:


    • After download and install Version 2.2
    • you choose "Import an Android code sample"
    04-08-_2016_07-33-27.jpg
    • select "Getting started", "Firebase Quickstarts for Android"
    04-08-_2016_07-34-06.jpg
    • hit "Next" and set your Project location (choose a very short path or compilation will fail later)
    06-08-_2016_20-37-11.jpg
    • hit "finish" and wait...
    • You might see this errormessage:
    06-08-_2016_20-42-29.jpg
    This is due to the missing google-services.json file in the right places.

    After trial and error I was successful with copying it in every \app and \app\src\debug folder
    06-08-_2016_20-47-38.jpg
    • The you need to connect your project with Firebase witch is easy over the "Tools-Firebase" Menu
    06-08-_2016_20-55-35.jpg
    • on the right appears the Firebase Assistant which helps you to have a smooth way to get the app and the Firebase together
    06-08-_2016_20-56-57.jpg
    06-08-_2016_21-01-24.jpg
    • Now you should be able to compile and run it
    • In the Firebase console "Auth"/ "Sign-In Method" you enable "EMail/Password provider" and then in "Auth"/ "Users" you add an user with an arbitrary Email and Password.
    • In the Firebase console "Database"/ "Rules" you enter:
    Code:
    // These rules require authentication
    {
      
    "rules": {
        
    ".read""auth != null",
        
    ".write""auth != null"
      
    }
    }

    • Now you start the app, log in and make your first post and comment and check what happends milliseconds later in the Firebase console "Database"/ "Data"
    1.jpg 04-08-_2016_08-46-57.jpg
    2.jpg

    If you have a second device connected in parallel you will notice, that the data wil be automatically synchronised. Even if one device is disconnected it will be synched later without user intervention. You can write a post offline and it will be synched if you be online later.

    The nodes beginning with "-KOJ..." are automatically created Ids to help rebuild the relations of the data on the clientside. Don't worry about complexity - the lib is doing the "dirty" work.​

    If you an experienced SQL developer you might shiver on the sight of the duplicated and denormalized data. But this is the way highly scaleable NoSQL works. It is very effective if you have millions of users using your app simultaneousely.

    Tags: #FIBAS #Firebase
     
    Last edited: Jul 18, 2017
    Kwame Twum, DonManfred and johndb like this.
  3. MarcoRome

    MarcoRome Expert Licensed User

    Fantastic Great Don +50 ;)
     
    Johan Schoeman likes this.
  4. DonManfred

    DonManfred Expert Licensed User

    New in V1.1 (See post #1):
    - Query object
    - DatabaseError object
    - One Event has changed signature.

    Code:
    Sub Reference_onCancelled(errnum As Int,error As String, errObj As Object)
        
    Log($"ref_onCancelled(${errnum},${error})"$)
        
    Dim err As DatabaseError = errObj
      
    End Sub
    - NEW Event onComplete

    Code:
    Sub Reference_onComplete(errorCode As Int, errorMessage As String, errObj As Object)
        
    Log($"ref_onCancelled(${errorCode},${errorMessage})"$)
        
    Dim err As DatabaseError = errObj
      
    End Sub
    It is - for example - called when you use removeValue() or updateChildren(Map map) after it finishes...

    - btw: updateChildren is new too...
    All untested :D
     
  5. fredo

    fredo Active Member Licensed User

    Thanks for the Update! I'm really greatful that you ar proceeding to work on this important library.



    However, while building an testapp I got this runtime error:
    Nevermind, found it. The settings in the Firebase console didn't match with my app setting.

    Code:
    ** Service (starter) Create **
    #-Service_Create
    starter_service_create (java line: 
    159)
    java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn
    't exist.
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.database.FirebaseDatabase.getInstance(Unknown Source)
        at de.donmanfred.FirebaseDatabaseWrapper.Initialize(FirebaseDatabaseWrapper.java:
    68)
        at b4a.example.fbdbrt.starter._service_create(starter.java:
    159)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
        at b4a.example.fbdbrt.starter.onCreate(starter.java:
    54)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:
    2877)
        at android.app.ActivityThread.-wrap4(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1427)
        at android.os.Handler.dispatchMessage(Handler.java:
    102)
        at android.os.Looper.loop(Looper.java:
    148)
        at android.app.ActivityThread.main(ActivityThread.java:
    5422)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    616)
    ** 
    Service (starter) Create **
    #-Service_Create
    starter_service_create (java line: 
    159)
    java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn
    't exist.
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.database.FirebaseDatabase.getInstance(Unknown Source)
        at de.donmanfred.FirebaseDatabaseWrapper.Initialize(FirebaseDatabaseWrapper.java:
    68)
        at b4a.example.fbdbrt.starter._service_create(starter.java:
    159)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
        at b4a.example.fbdbrt.starter.onCreate(starter.java:
    54)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:
    2877)
        at android.app.ActivityThread.-wrap4(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1427)
        at android.os.Handler.dispatchMessage(Handler.java:
    102)
        at android.os.Looper.loop(Looper.java:
    148)
        at android.app.ActivityThread.main(ActivityThread.java:
    5422)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    616)
    java.lang.RuntimeException: Unable 
    to create service b4a.example.fbdbrt.starter: java.lang.RuntimeException: java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist.
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2887)
        at android.app.ActivityThread.-wrap4(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
    1427)
        at android.os.Handler.dispatchMessage(Handler.java:
    102)
        at android.os.Looper.loop(Looper.java:
    148)
        at android.app.ActivityThread.main(ActivityThread.java:
    5422)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    616)
    Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn
    't exist.
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:206)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
        at b4a.example.fbdbrt.starter.onCreate(starter.java:
    54)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:
    2877)
        ... 
    8 more
    Caused by: java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn
    't exist.
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
        at com.google.firebase.database.FirebaseDatabase.getInstance(Unknown Source)
        at de.donmanfred.FirebaseDatabaseWrapper.Initialize(FirebaseDatabaseWrapper.java:
    68)
        at b4a.example.fbdbrt.starter._service_create(starter.java:
    159)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
        ... 
    11 more
    The setup in the Firebase console seems OK,
    could it be a mistake on my side?
     

    Attached Files:

    Last edited: Sep 1, 2016
  6. fredo

    fredo Active Member Licensed User

    Thanks for your ongoing efforts, it's really great.

    EDIT: Those problems are solved since #35

    However, there are two little problems one little problem I can't solve and I hope there is just a typo in the lib...

    20-08-_2016_14-39-18.png

    I used your DatabaseExample project and added the following code in Activity_Create (see attached project) right after the inits of your Database and DatabaseReference:

    Code:
    ' fredo test area
        '
        ' A database testfile "fir-quickstartsforandroi-93d9a-export.json"  for IMPORT into the Firebase database is located in the Files-folder of this project.
        '
        Dim strTopNode As String = "testnode1" ' If you create this node at the root via Firebase console and import the "fir-quickstartsforandroi-93d9a-export.json" UNDER this node the other existing data stay untouched.
        ' ────────────────────────────────────
        ' EXAMPLE
        ' ────────────────────────────────────
        ' (fbdbtestdatabase)
        '        * testnode1
        '                * post-comments
        '                    *  -KOJH1oVe...
        '                    *  -KO_BCC6e...
        '                *posts
        '                *user-posts
        '                *users
        '
        ' ────────────────────────────────────

        
    ' Original in JAVA from here --> https://github.com/firebase/quickstart-android/blob/master/database/app/src/main/java/com/google/firebase/quickstart/database/NewPostActivity.java

        
    Dim strUid As String = "11223344"
        
    Dim mapPostValues As Map
        mapPostValues.Initialize
        mapPostValues.Put(
    "Uid", strUid)
        mapPostValues.Put(
    "UNam""testuser")
        mapPostValues.Put(
    "Title""### TheTitle ###")
        mapPostValues.Put(
    "Body""... TheBody ...")

    '###Problem 1: Here should be a key generated like "-KOJ65eZv...." '' [SOLVED with Don's lib 1.20]
        Dim key As String = ref.child("posts").push.Key
        
    Log("#-  key=" & key)
        
    Dim childUpdates As Map
        childUpdates.Initialize
        childUpdates.Put(
    "/posts/" & key, mapPostValues)
        childUpdates.Put(
    "/user-posts/" & strUid & "/" & key, mapPostValues)

    '###Problem 2: runtime error "Map cannot be cast to java.util.map". Why??
        ref.updateChildren(childUpdates)

    The code snippet is transformed from an official Firebase JAVA source from here: https://github.com/firebase/quickst...base/quickstart/database/NewPostActivity.java
    Code:
    // [START write_fan_out]
        
    private void writeNewPost(String userId, String username, String title, String body) {
            // Create new post at /user-posts/$userid/$postid 
    and at
            // /posts/$postid simultaneously
            
    String key = mDatabase.child("posts").push().getKey();
            Post post = new Post(userId, username, title, body);
            
    Map<String, Object> postValues = post.toMap();

            
    Map<String, Object> childUpdates = new HashMap<>();
            childUpdates.put(
    "/posts/" + key, postValues);
            childUpdates.put(
    "/user-posts/" + userId + "/" + key, postValues);

            mDatabase.updateChildren(childUpdates);
        
    }
    // [END write_fan_out]
    (Another testproject to work with the Firebase Realtime Database would be here)

    I know that this kind of database is not your top field of expertise but I hope together we can find out the next steps to ensure that the library is working in all aspects.


    Tags: #FIBAS #Firebasedatabase
     

    Attached Files:

    Last edited: Oct 5, 2016
  7. fredo

    fredo Active Member Licensed User

    @DonManfred --> Did you had a chance to try Erels solution to the problem with the cast of Java-map to B4A-map?

    This lib is so extremely beneficial for the B4A world that I mean, it is worth to keep at it.

    If you will make the changes on the library-side, I am willing to test the database functionality on the B4A-side and provide constant feedback to you.


    If the library for the Firebase Realtime Database is at 100%, I'm happy to write a small tutorial for the Community.
     
    Last edited: Sep 21, 2016
  8. Serdar K.

    Serdar K. Member Licensed User

    Hi,

    DonManfred, thanks for making this awesome library available for B4X world.
    Thank you very much for your efforts in this forum.

    I have a little weird problem running this library :
    Maven artifact not found com.google.firebase/

    First one is solved but with the function signature issue is going on.
    I'm just trying the demo supplied with the library.Only the db connection is changed.

    Did anyone experience the same ? Is there another version of the demo application compatible with library's 1.1 ?

    Regards,
    Serdar
     
    fredo likes this.
  9. Serdar K.

    Serdar K. Member Licensed User

    Somehow i didn't see the message over my message, that was the problem.
    Thanks :)


     
    fredo likes this.
  10. luke2012

    luke2012 Well-Known Member Licensed User

    @DonManfred first of all, my compliments for this wonderful firebase library :)
    I'm investigating if it is possible to store and retrieve a password using the realtime database.

    So the user should be able to write and update this password.
    Is it possible?

    Thanks in advance.
     
  11. DonManfred

    DonManfred Expert Licensed User

    I guess i sorted it out... Setting a Map as a Value for a databasereference works fine here in my lastest tests. I´m figuring/investigating out more
     
    fredo and johndb like this.
  12. DonManfred

    DonManfred Expert Licensed User

    Create a global Map for the Database
    Code:
    Dim db As Map
    After you initialized the database and get the databasereference the event onDatachanged will be raised with the content.

    Code:
    Sub Reference_onDataChange(snapshot As Object)
        
    Log($"ref_onDatachange()"$)
        
    Dim snap As DataSnapshot = snapshot
        
    Dim m As Map = snap.Value
        db = m
    end sub
    You now can use the Map "db" to make changes....

    Code:
    Sub Button1_Click
        
    If db.IsInitialized Then
            
    If db.ContainsKey("users"Then
                
    Dim userlist As List = db.Get("users")
                
    For i = 0 To userlist.Size-1
                    
    Dim user As Map = realtime.Value2Map(userlist.Get(i))
                    
    Log(user)
                    
    If user.Get("name") = "DonManfred" Then
                        
    Log("DonManfred found (me).. "&user.Get("kdnr"))
                        
    Log("KDNR="&user.Get("kdnr"))
                        
    Log("increment calls... is now "&user.Get("calls"))
                        
    Dim calls As Int = user.Get("calls")
                        calls = calls +
    1
                        user.Put(
    "calls",calls) ' update value in map
                        userlist.Set(i,user) ' overwrite the user in the list
                    End If
                
    Next
                db.Put(
    "users",userlist) ' write the userlist back to the database-map
            End If
            ref.Value = db 
    ' write the new database
        Else
            
    Log("Global Map not initialized!?")
        
    End If
    End Sub
    Please note that for this examplecode you need V1.2 of the FirebaseRealtimedatabase (See Post #1)
     
  13. DonManfred

    DonManfred Expert Licensed User

    The above Button click code will produce changes in the realtime database:
    This is a screengrap from my PCs Browser watching the Databasecontent

    http://recordit.co/8ddEavoaDc
     
    fredo and johndb like this.
  14. fredo

    fredo Active Member Licensed User

    Thank you @DonManfred for your ongoing efforts!

    I know this is a big project and needs a lot of work to bring it up to 100% functionality.

    But I'm sure this will help thousands of B4A developers to create modern social based applications "the rapid way".

    I will try the functionality the next days and give you feedback then.
     
  15. fredo

    fredo Active Member Licensed User

    OK, the push function generates the special key. This is great!

    However, there still is the issue with the updateChildren function,

    Code:
    Sub writeNewPost(strUid As String, strUNam As String, strTitle As String, strBody As StringAs Boolean
       
    Log("#-writeNewPost, strUid=" & strUid & ", strUNam=" & strUNam & ", strTitle=" & strTitle & ", strBody=" & strBody)   
       
    Dim mapPostValues As Map
       mapPostValues.Initialize
       mapPostValues.Put(
    "Uid", strUid)
       mapPostValues.Put(
    "UNam", strUNam)
       mapPostValues.Put(
    "Title", strTitle)
       mapPostValues.Put(
    "Body", strBody)
       
    Dim strPostValues As String = raMapToJson(mapPostValues)

       
    Dim key As String = mDatabase.push   
       
    Log("#-  raw key=" & key)   
       
    ' Creates this -->    ' #-  raw key=https://fbdbzzzz-xyxyxyx.firebaseio.com/testnode1/-KT4Xi6oGKr0wye-zOoO ' The last part this is what we need = OK
       If key.Length < 2 Then    
         
    Return False
       
    End If
       
    '
       ' Strip the autogenerated optimized key
       key = key.SubString(key.LastIndexOf("/") +1)
       
    Log("#-  key=" & key)   
       
       
    Dim strUk1 As String = "/posts/" & key
       
    Dim strUk2 As String = "/user-posts/" & strUid & "/" & key
       
    Log("#-  strUk1=" & strUk1)   
       
    Log("#-  strUk2=" & strUk2)   
       
       
    Dim childUpdates As Map
       childUpdates.Initialize
       childUpdates.Put(strUk1, strPostValues)
       childUpdates.Put(strUk2, strPostValues )
       mDatabase.updateChildren(childUpdates)    
    ' <<<<<<----here it breaks
       
       
    Return True
       
    End Sub
    02-10-_2016_15-41-43.jpg

    but luckily Erel has a solution for this:

    02-10-_2016_15-47-44.jpg

    @DonManfred you need to take it from here, since I'm still in the basecamp of "Wrap Everest"...
     
    Last edited: Oct 2, 2016
  16. DonManfred

    DonManfred Expert Licensed User

    try v1.21
     
    fredo likes this.
  17. fredo

    fredo Active Member Licensed User

    Code:
    java.lang.ClassCastException: anywheresoftware.b4a.objects.collections.Map cannot be cast to java.util.Map
        at de.donmanfred.DatabaseReferenceWrapper.updateChildren(DatabaseReferenceWrapper.java:
    213)
        at b4a.example.fibadb2.testfibart._writenewpost(testfibart.java:
    840)
        at b4a.example.fibadb2.testfibart._submitpost(testfibart.java:
    778)
        at b4a.example.fibadb2.testfibart._btnsend_click(testfibart.java:
    445)
        at java.lang.reflect.Method.invoke(Native Method)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    157)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
        at anywheresoftware.b4a.objects.ViewWrapper$
    1.onClick(ViewWrapper.java:78)
        at android.view.View.performClick(
    View.java:5609)
        at android.view.View$PerformClick.run(
    View.java:22259)
        at android.os.Handler.handleCallback(Handler.java:
    751)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    154)
        at android.app.ActivityThread.main(ActivityThread.java:
    6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    865)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    755)
    Code:
    if (_key.length()<2) {
    //BA.debugLineNum = 
    317;BA.debugLine="Return False";
    if (truereturn anywheresoftware.b4a.keywords.Common.False;
    };
    //BA.debugLineNum = 321;BA.debugLine="key = key.SubString(key.LastIndexOf(\"/\") +1)";
    _key = _key.substring((int) (_key.lastIndexOf("/")+1));
    //BA.debugLineNum = 322;BA.debugLine="Log(\"#-  key=\" & key)";
    anywheresoftware.b4a.keywords.Common.Log("#-  key="+_key);
    //BA.debugLineNum = 324;BA.debugLine="Dim strUk1 As String = \"/posts/\" & key";
    _struk1 = "/posts/"+_key;
    //BA.debugLineNum = 325;BA.debugLine="Dim strUk2 As String = \"/user-posts/\" & strUid &";
    _struk2 = "/user-posts/"+_struid+"/"+_key;
    //BA.debugLineNum = 326;BA.debugLine="Log(\"#-  strUk1=\" & strUk1)";
    anywheresoftware.b4a.keywords.Common.Log("#-  strUk1="+_struk1);
    //BA.debugLineNum = 327;BA.debugLine="Log(\"#-  strUk2=\" & strUk2)";
    anywheresoftware.b4a.keywords.Common.Log("#-  strUk2="+_struk2);
    //BA.debugLineNum = 329;BA.debugLine="Dim childUpdates As Map";
    _childupdates = new anywheresoftware.b4a.objects.collections.Map();
    //BA.debugLineNum = 330;BA.debugLine="childUpdates.Initialize";
    _childupdates.Initialize();
    //BA.debugLineNum = 331;BA.debugLine="childUpdates.Put(strUk1, strPostValues)";
    _childupdates.Put((Object)(_struk1),(Object)(_strpostvalues));
    //BA.debugLineNum = 332;BA.debugLine="childUpdates.Put(strUk2, strPostValues )";
    _childupdates.Put((Object)(_struk2),(Object)(_strpostvalues));
    //BA.debugLineNum = 333;BA.debugLine="Log(\"#-  childUpdates=\" & childUpdates)";
    anywheresoftware.b4a.keywords.Common.Log("#-  childUpdates="+BA.ObjectToString(_childupdates));
    //BA.debugLineNum = 334;BA.debugLine="mDatabase.updateChildren(childUpdates)";
    mostCurrent._mdatabase.updateChildren(_childupdates);  <<<<<<<<<<<<<<<---------Line 840
    //BA.debugLineNum = 337;BA.debugLine="Return True";
    if (true) return anywheresoftware.b4a.keywords.Common.True;
    //BA.debugLineNum = 340;BA.debugLine="End Sub";
    return false;
     
    Last edited: Oct 4, 2016
  18. DonManfred

    DonManfred Expert Licensed User

    I´m not sure but i guess you or me doing it wrong :)

    Using
    Code:
    ref.Initialize("Reference",realtime.getReferencefromUrl("https://myfbname.firebaseio.com/"))
    i get a reference to the HOLE database...
    I can get a map holding the content including all subfolders.

    And i can change the map and add new items to it (or add new lists (folders) to it), set the database back as value for the reference i am using.
    It will overwrite the hole content in the db. voila, works.

    If i use
    Code:
    ref.Initialize("Reference",realtime.getReferencefromUrl("https://myfbname.firebaseio.com/users/"&User.Uid&"/"))
    from inside a logged-in-event using firebaseauth
    Code:
    Sub Auth_SignedIn (User As FirebaseUser)
        
    Log("SignedIn: " & User.DisplayName)
        lblName.Text = 
    "Hello: " & User.DisplayName
        lblUID.Text = User.Uid
        lblUID.Tag = User
        logged = User
        ref.Initialize(
    "Reference",realtime.getReferencefromUrl("https://myfbname.firebaseio.com/users/"&User.Uid&"/"))
    i´ll get a "partially" databasecontent.
    In this case the content inside /users/{userfolder}/ but with all subfolders (if there are any)

    I can get a map holding the complete content of /users/{userfolder}/

    I can add values to it and just reSet the value of the reference to the new map content... Voila, works.

    Works pretty fine for me.

    Note that i´m not using any updatechildren or such method...
    I guess it have to be used in another way.

    I´m just changing the map-content and write the map back to the reference.Value

    Maybe i´m doing it wrong. Honestly i dont know :D

    But that said i just have to say that i did not do much reading on the firebase-examples or tutorials on how to use firebase db

    Maybe i did miss some important info ;-)
     
  19. fredo

    fredo Active Member Licensed User

    Thanks for your ongoing work.

    "updateChildren" is an essential function in the NoSQL world.

    NoSQL is not intented to download the database from the root. It is event-driven! You just set a path to the existing item or create new items and inform Firebase RTDB that there is an update. Then all the magic around transactions etc. is handled by the RTDB.

    Have a short look at this and this to get an idea what would be best to set a reference.

    The fantastic difference to other RDBMS is that you structure and store your data in a special way so that you can use it later to direct load it in your views. The concept is optimized for huge ammounts of operations as needed for social oriented apps.

    Good read with JAVA examples: https://firebase.googleblog.com/2015/09/introducing-multi-location-updates-and_86.html

    E.g. like this:
    Code:
    Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
    // Generate a new push 
    ID for the new post
    Firebase newPostRef = ref.child(
    "posts").push();
    String newPostKey = newPostRef.getKey();
    // Create the data we want 
    to update
    Map newPost = new HashMap();
    newPost.put(
    "title""New Post");
    newPost.put(
    "content""Here is my new post!");
    Map updatedUserData = new HashMap();
    updatedUserData.put(
    "users/posts/" + newPostKey, true);
    updatedUserData.put(
    "posts/" + newPostKey, newPost);
    // 
    Do a deep-path update
    ref.updateChildren(updatedUserData, new Firebase.CompletionListener() {
       @Override
       
    public void onComplete(FirebaseError firebaseError, Firebase firebase) {
           
    if (firebaseError != null) {
               System.out.println(
    "Error updating data: " + firebaseError.getMessage());
           
    }
       }
    });

    Maybe this Testproject for Firebase Realtime Database will help to test...


     
    Last edited: Oct 3, 2016
    Multiverse app and luke2012 like this.
  20. DonManfred

    DonManfred Expert Licensed User

    v1.22 does not give an error for me but i´m not sure to do it right :)
    Give it a try. Download in Post #1
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice