2017년 8월 20일 일요일

Using TinyWebDB - a web based persistent data solution


There are some people asking in the forums about how to use TinyWebDB, so I want to help.  I'm not going to bother telling about how to setup the WebDB...that information is available here.  Once you've gotten the service setup, read on.

Let's start with the components:

⦁ 1 label
⦁ 2 text boxes (one set to multiline)
⦁ 1 button
⦁ 1 listpicker
⦁ 1 clock
⦁ 1 TinyWebDB
⦁ 1 Notifier
⦁ 1 VerticalArrangement
⦁ 1 HorizontalArrangement

You can see how I've arranged the app in the picture to the left, as well as the names assigned to the elements.  


Once you've gotten it setup how you want it, open the blocks editor and let's get to it.

There are relatively few blocks to this app, and not a lot of complexity.  The first thing we need to do is define a global variable, listOFTags, as an empty list.

Once that's done, let's setup the button click event.  



We need a mutated if block to get an else condition.  We're going to test whether our list contains the name of the document, txtDocName.text.  I use the trim block from the text drawer to make sure there's no trailing spaces the user forgot to remove but this isn't necessary.  If the name entered is in the list, we want to alert the user and have them choose something else to call it, so we need the Notifier.ShowMessageDialog populated with an alert of some kind.  We also want to clear the text box of any text to make sure the user has to enter something else.  For the else portion, since the entered name isn't already in the list, we want to add it to the list, and store it as a tag in the WebDB with the value being the text of the other text box.  Once that's done, we need to store another value, this time the list, under the tag list so we can import all the data from the WebDB.  Because there's no GetTags function for the WebDB, we have to have a way of knowing what is saved there so we can view the info later, without having to go to the website to look.  Now we need to load the list into the listpicker, enable the listpicker, and remove the text from the two text boxes.  

With the WebDB, because there is an Internet component to it, it has a unique event you won't find with the normal TinyDB: ValueStored.  With this event we can let the user know that the info they uploaded to the DB was saved, and didn't result in an error, so we'll use the notifier to show an alert that simply says "Database successfully updated."  

Let's fix up the Screen1.Initialize and lstpLoad.AfterPicking events with a TinyWebDB.GetValue command.  




The tag for the Screen will be the same we used for uploading our list to the DB: list.  For the listpicker, the tag will be the selection from the listpicker, because they're all unique tags on the DB with the entered text of the other box as their values.

Perhaps you're wondering what the clock is for...well, as I show on my Fun With the Clock examples page, it's for enabling or disabling the save button depending on whether there's text in the DocName text box.  You should make sure the interval of the clock is set to 50 milliseconds and then put an ifelse statement into the .Timer event and check for whether the text of DocName is empty; if it is, we need to disable the button, otherwise we enable it.

Now that those simple events are done, we'll configure the TinyWebDB.GotValue event.  Remember that we are retrieving a value in the Screen1 event, and that tag/value pair is a list.  So the first thing we need to check is whether the tag received is equal to list and whether the value of that tag is a list.  If both conditions are true, we set the global variable to the value of the DB and set the elements of the listpicker to the global variable.  This will give us our persistence with the database.  Without this logic check, we won't be able to read any of the tags saved on the DB once the app has been closed.  If those two checks are false (the tag isn't list and the value isn't a list) then they are, by process of elimination, equal to the selection of the listpicker and associated text, so we set the txtDocument.Text equal to the value and we print to the label Contents of {tagfromWebDB}:

And we're done!  Download the source below.

TinyWebDB.aia







TinyWebDB login


As you saw on the first example, TinyWebDB can be used to store a text document as a value for a title as a tag.  In this example, I'm going to show you how you can use TinyWebDB to create a login screen for your app.  Keep in mind that your webDB is not secure; if someone finds out the web address for it, they could easily get the usernames and passwords you're storing on it.  It's probably better to use a different type of database.  Having said that, let's begin.


Components and design

We need the following components for this app: 



⦁ 3 buttons
⦁ 5 textboxes
⦁ 1 password textbox
⦁ 1 clock
⦁ 1 TinyWebDB
⦁ 5 vertical arrangements (1 optional)
⦁ 3 horizontal arrangements
⦁ 1 Notifier

Set the screen scrollable value to false.  Two of your vertical arrangements will be used to simulate screens for the user: the login screen and the account-creation/working screen.  Inside each of those vertical arrangements we use a horizontal arrangement to place our login and submit buttons next to our textboxes the user will use to either create their account or login to their account.  In my screenshot you will notice that I have the fifth horizontal arrangement for the bottom two textboxes of the working screen, though this is unnecessary.  Once you get the design screen setup either like mine or to your liking, let's move on to the blocks editor.

Blocks




Let's begin with the variable creation and Screen.Initialize event.  We need an empty list to hold all the usernames we'll have in the app, and the screen should retrieve the value of this list from the webDB every time the app is run, to make sure we have the most up to date information.  The tag for the list should be something that is easily distinguishable, and not going to be overwritten by a username someone may choose, e.g. userList.  If you're familiar with most of my tutorials, you'll quickly recognize the Clock.Timer event and it's purposes, but if not, head over to my Fun with the Clock page for an explanation.

The procedure, as it says in the picture, isn't really necessary, but I created it to make the GotValue event just a little less block-heavy; you can choose to eliminate it if you'd like to put these blocks into the GotValue event once we get there.  For the ValueStored event, you'll see that we switch back to the login screen everytime someone creates an account, and the text of the screen switch button is changed to allow for the user to switch to the account creation screen if they want to make a new account.

The next step of the process for us will be setting the blocks of the login and screen switch buttons.  




In order to know which screen we're on, we need to check the text of the switch button,and load the opposite screen (arrangement) and change the text to the other value we'll check against.  For the login button, we'll be checking the user list we load at screen initialize to see if the username entered into the textbox exists; if it does, we request the login info from the webDB or we tell the user that their username isn't correct.  You'll notice in the image to the right that I am using the text trim block on the entered value of the username textbox; this is because the username saved to the database and the list without a space at the end or beginning is not the same as the username with a space at either position.

The next event to setup is the submit button event; the one that creates an account.  


This button also checks against the loaded user list and warns the user if the username they picked is already in use.  If it's not in the list, we will create the account.  The first step is to add the username to the list and then update the webDB tag for the list.  After we update the list, we create the new tag and value pair for the user.  The username will become the tag, and the values entered into the textboxes will be a list of values under the username tag.  You might have noticed the select list item blocks in the procedure earlier; this is why they exist.  Their indices are specific to these values we're saving for the user; if the positions change here, they have to be changed in that procedure (or the GotValue event).

The last and final piece of the puzzle is really the meat and potatoes of this app: the TinyWebDB.GotValue event.  The first thing we want to do is prevent there from being any runtime errors when the screen loads, so we need an if statement here to check that the value of the tag retrieved is not empty.  We won't be using an else portion because if it is empty we just won't do anything.  If it's not empty, we need to see if the data being requested is from the screen initialize event and load the user list into the app.  The is a list? check I have in there might be superfluous, but it's just to be entirely sure that there won't be a runtime error if we try to check a name in a list that isn't a list.  If the tag is userList and the value is a list, we load the global variable with the list of users, else we will do our login check.  In order to login to the app, the user must have entered a valid username and the password associated with it.  The password (as I have the blocks setup) is always the first item of the list of data saved for the username tag.  If the value entered into the password textbox is not the same as the first list item of the value retrieved from the webDB then either the username or the password has been entered incorrectly and they need to retry so we give them a notification error and reset the textboxes.

Once we've checked that the username and password are correct, we can load the data for the user from the webDB.  


So they know that they have logged in, we'll greet them with a toast message at first, then swap screens and load their data into the app. Then we'll just set the login screen textboxes to blank and we're done.

You can download the source code below.  Happy App Inventor-ing!









Login Template AI2


I am currently using A Login template for App Inventor as the login template which I have used to recreate on App Inventor 2, but my issue is that I cannot seem to register after entering my name, password, confirm password, and email.
The errors for the user input (Not same password and repeat password, username cannot contain '@', etc.) occur as the template specifies, but when I press "Register," nothing happens.
I am modifying this template and submitting it for a contest, and the contest specifies that the app must be developed in AI2.
Any and all help would be greatly appreciated ASAP!
I have attached the *.aia file of the app for reference.

--
It stops for me to at  "Register" .... took a while to figure that is the ButtonOK_Reg block.  I guess it stops here because I see no code here other than the TinyWebDB call.  Trying a DoIt, after properly filling in the fields, it does not appear the fields are transferring data.

So, I would start the hunt here Rishi ..... I can not test your TinyWebDB   calls.   I put the Screen1.TitleBlock there to give an indication the button gets pressed.   It definitely does get pressed.
I also deleted the Sound.Click as events of that type can sometimes inhibit the events in the blocks following them.

--
If you're looking for a login template designed in AI2, and utilizing the TinyWebDB, check out my tutorial on this very thing

--

Core Device Discovery


The Core Device Discovery application for Modern Robotics Inc. Core System allows you to view module information, test, and run most aspects of each module from your PC. It is recommended that the Core Power Distribution module be used in line with any connected controllers however controllers may be connected directly to your computer as well. To get started, view the user guide below and download thapplication.
Connect Module to your computer as shown below.
Connections

  
2MB PDF File, Last Updated 4/11/2017
11MB Application, Last Updated 2/27/2017.
7.86MB Zip Folder, Last Updated 11/24/2015.

 **The Mac version of Core Device Discovery is currently behind the Windows version and does not support new features at this time. Due to security restrictions, Core Device Discovery for Mac must be manually cleared past the Gatekeeper. To do this go to System Preferences -> Security & Privacy -> General and allow CDD access to your computer. This action will only need to be taken once. Core Device Discovery has not yet been tested on Yosemite.

For assistance, call Modern Robotics support 786-393-6886 or email support@modernroboticsinc.com.