Firebase DB with App Inventor tutorial

I advise experimenting with use of compound tags like "2/Points" to get directly to individual values.
You would want to be able to update your data with a tweezers after loading it with a shovel.

I plead ignorance .. I have never heard of "Compound Tags" .. where can I read about these?

I would love to use tweezers instead of a shovel.

If you examine the place in the Firebase web site where it shows the contents of your databases, they are shown as trees, with the root of the tree on the left, like a PC file system directory structure.

Each twig of this tree can be reached by a tag that looks like full path and file name of a PC file, like C:\Users\ABG\Dropbox\AI2\Projects\chess\chess.aia
except Firebase uses / in its tags instead of the \ that Windows uses in its file systems.
So if I used the Firebase tag
Users/ABG/Dropbox/Projects/chess/chess.aia I might retrieve a value for the contents of chess.aia, had I uploaded it there.

The term 'compound tag' is my idea.
The '/' functionality works.

Using the firebase component blocks (as you have shown in your example) you will have to call back the entire contents of tag "2" to your app in order to edit any item therein.

If you use the web component to store data on firebase as firebase lists, then you will be able to drill down and edit/retrieve individual tags within your list structure.
(note: you could use the firebase component blocks to do this but it would take a lot of work)

See here:

and here:

for how to do this

Also a word of warning, Firebase will happily create tags/nodes with numbers if you don't supply them, but it can get a bit upset if you provide the numbers as tags/nodes (especially 0 and 1).

Ahhhh.. I understand. Thats kind of what I was hoping to avoid. I was also using the wrong words earlier, when I said "If I have to read in the entire list (I'm using Dictionaries) then I will but if I can edit only the pairs I need I would prefer that." that's what I am already doing now. I am reading in Tag 2 and all of its value. I was wanting to drill down to the exact pair, edit it, and save the pair and be done. I now see I cannot do like I had hoped.

Which brings me to my current problem. I can login to my app using the acct data in Tag 1 .. load the data from Tag 2 .. and make an edit to a pair in Tag 2 just fine. But many times when I save the data for Tag 2 back I am overwriting it with the data in Tag1 except for the data in the pair I edited. Its confusing.

I am trying to use the same Read and Write routines (its just good programing not to duplicate routines) and I eventually will solve the issue through trial and error like I always do.. but sheesh!

If I get THAT kind of stuck then I will post some blocks and ask for help. But for now, "D*mn the Torpedoes!"

I am quickly realizing that I am at the end of my knowledge and do need some help now.

I start of with this example data set:

example04

At this point life is good. Here is the routine I am running along with the Read and Write routines:

example01

I read in my target data.. make the edit to the pair I need.. and save the target data back. I then read in the orginal user data.


..the rest of the read blocks are here but you get the idea

Its as lean and clean as I know how to make it. If I login to my app with lets say user #2 and want to edit the data for user #1 I end up with this:

example05

..with the exception of the pairs that I edited.. they saved my edit and are correct. Everything else seems to be from user 2. I'm confused!

Where are you getting global targetIndex from?

Ai2 lists are 1 based, you firebase data (tags) appear to be 0 based.

Also sign in as user2 ? How are you "signing in" ?

I define target global targetIndex in the routine immediately before and I even check that it is the correct value.

I do sign in as user 2.

I dont understand what you mean by "Ai2 lists are 1 based, your firebase data (tags) appear to be 0 based" .. maybe this is my problem? The tag I am using is what I am calling my user number (the 1, 2 and 3) so is that not "1 based" since there is 1 tag?

As I see it my mistake is someplace with my tags.. the design, or the use of.. so I think you may be on to something.

This could also be an issue, which I advised on earlier in the topic. It may be better to assign strings to users as opposed to numbers (user1, user2, user3).

I still do not understand your signing in process and how that might affect access to the data. I am assuming you are NOT using firebase authentication.....

Correct, I am not using Firebase authentication. The only reason I am using Firebase at all is because I need to share the data between all the users. Any user will be able to edit any record. That, and I already had a Firebase acct. Is there a better solution perhaps? Would Coud DB work better for my needs?

Your original warning appears to be what is happening here I think. Everything works fine when if I hard code the indexes but to me thats just sloppy and a lot of extra coding with duplicate routines.

You could also be trying to do things out of sync

Everything next to the red bar should be happening in the .GotValue event, but then you call readCCUserData again which could create an endless loop ?

hmm.. let me see if I can explain a little more of my logic.

I have one GotValue routine for FirebaseDB1. I use it to read in the userdata when a user logs in. Lets say I am user #1 and I login. I now have all my variables assigned with my data.

I toddle along and need to edit a data pair for another user. I change the 'index variable' and do a call to read in the new user data using the same read routine. I make my edit and save the data back. I then change the 'index variable' back to my user number and read in my data.. all using the same read and save routines and GotValue event. Is this not the best way to handle this? I am guessing not..

I do not understand why you say the blocks next to the red bar need to be moved to the GetValue event. Those are the blocks I am using to edit the other users data. If they are part of the GetValue event they will fire every time ANY user is read, including my own data when I login. Thats not what I need to happen.

This is where I am having trouble, my big picture logic. I only know so much about Databases and am trying to figure this out. None of this is in production so I am not opposed to going back to the drawing board and redesigning anything. I just want to know I am doing it right, and it works.

This is more about the asynchronous logic used by AppInventor.

When you use the .GetValue block, the output is returned in the .GotValue event. You can't do anything with the value you want until you have got it. If you try to do other things with your intended value before you have got the value (which is what your save and second read procedures are trying to do, you can then expect data or program errors. You do not show your entire .GotValue block so I can only guess at what you are trying to achieve....

Still do not understand the logging in stuff....

I understand your point, but if you look at the blocks I posted above I think I have that covered. My 'readCCUserData' procedure calls the GetValue event.. which in turn calls GotValue .. so I have the data at that point, at least this is my understanding.

At one point I even placed a Notifyer ShowMessage block in the GotValue routine after one of my variables to show the value after it was read in and it was correct. That block has since been removed..

I then edit the data pair that I need, and when I check, it's successful.

I then run the 'saveCCUserData' procedure to write the data back.. same as before.. that procedure creates the updated list and calls the StoreValue event. When I walk through this in my head, it should work fine. I then read MY user data back in and continue on..

I don't know how else to explain the logging in stuff. I login with my account (user number 1) and want to edit the data for another user .. for the sake of example, user number 2. I am using the user numbers for my indexes and tags since they are the same. User 1 is Tag 1 in the database, etc.. that just made sense to me.

I hope I am making myself clear, this is obviously not my field of expertise.

Here is the entire GotValue event. I did not include the whole thing before because of the size. Its small now so I could get it to fit on the screen. As you can see the data structure coincides one to one with the SaveData routine.

I will leave you to plough your own furrow for a while :wink:

Thanks for the assistance .. it really does help when someone else makes me think it through. If there is an answer I will find it eventually.

It wouldn't hurt to read a few articles about how to structure data in FireBase

I asked for some at the beginning of this entire conversation.. that's what got this whole thing started. I will figure this out if it's the last thing I do.

Another question please.. what does this mean? I get this when I try to perform a "Do It" on some of my blocks..

image

Obviously this has something to do with my issue..