Dataviewer Unexpected Behaviour

Hi,
I am fetching data from Forebase DB and storing them locally using “Own Table Data Source” then displaying them using Dataviewer. Upon clicking it should switch screens.

The data is for orders, and it will switch to order details screen upon clicking the item in the Dataviewer.

Currently, It fetches the Data normally from the Firebase and at the first glance it is working as it is displaying them correctly using the Dataviewer. However, when I click it didn’t switch “navigate”, so I started to investigate and it is when I found that only one of the list of data is actually stored (using number of rows in the Table). It is unpredictable as the number of rows stored is changing randomly. Each time I fetch a new list I delete the rows from the Table (System Table - My Orders Meta Data) and then fetch the data and store them.

I have checked multiple of sources for this but nothing is leading anywhere to a solution. Find attached the screens of the actual behaviour of the System and the logic blocks.

Logic Blocks
Firstly, Deleting What is in the Local DB
Thunkable Dataviewer Issue2

Then Fetch the list of Data from Firebase DB and Store them in the Dataviewer
Thunkable Dataviewer Issue3

The Item Click in the Dataviewer which shows the Selected Row ID (Which is different for each selected row in the Dataviewer, even though the number of rows in the Table is 1 in this scenario)

Application View
Once it is opened this is the list of Orders that are fetched from the Firebase DB

Upon Selecting an Item this is the rowID displayed which varies from each row to another

Then the number of rows actually stored in the Table (Local table):

Finally if I refrech manually this is the only order remaining in the Dataviewer


n

2 Likes

The image you shared is truncated and therefore does not provide enough information for others to see where would the problem could be.

Can you provide a more meaningful copy of you codes along with what is expected in your Firebase (your key structure).

@muneer Can you check the new edit, I have added a screenshot of the screens and the blocks. It should show everything in details. I assume the extra parameters are not needed as the data is displayed correctly.

If something not clear let me know and I will update it

1 Like

I’m sorry to say there is no enough information to show the logical flow of the app. In this case I can give you one simple advice.

Move the Fetch Orders inside the delete all rows block.

1 Like

Regarding the logic, I fetch a list of ids from the firebase db, then iterate over each one of these ids and get the actual data (so each id is pointing to a variable stored in the firebase). Afterwards I create a new row in the Local table and assign the attributes the same values I retrieved from firebase. The last cycle happens for each id. I expect that once I select one of orders (rows in the local table) certain message will be displayed. However, at the moment only work with one element and the rest of the element it doesnt. Therefore, I have checked after retrieving the data from firebase I display a message to show the number of rows stored it shows only one.

Other workarounds I have tried but didnt solve the issue: @muneer

  • putting fetch method inside the deletion (assuming that deletion takes time so it might result to that behaviour), didnt solve it
  • putting wait command after the deletion and after each fetch of an order (inside the list of order ids), it didnt solve it.
  • calling the retrieval recursivelly as long as the number of rows is not matching the size of the ids list (and check if the item/order exist or not). It didnt work and kept retrieving data from firebase and displaying them on the Dataviewer without actually storing them in the local table.

Conclusion, either I am doing something wrong, or there is something wrong when I call create row for the local table.

1 Like

It is very clear that there exists a gap between the logic that you describe and the logic that you code in blocks and because you do not want to show your blocks apart from the snippets you showed it is difficult to suggest you anything.

If you don’t want to share your app then create a sample project that just reproduce the problem with sample data that you can share.

1 Like

Hi @darweeshworkqxl, I’d like to take a closer look at your project to help you figure this out. I’ll follow up with you on Intercom!

Best,
Cassandra

2 Likes

@muneer
Hi, Thank you for your advices so far. I will share the blocks and my different attempts here as the issue has been disturbing for quite some time (also maybe others can learn), although I have tried to contact the Thunkable Staff through the Intercom chat but nothing yet from their side.

The First attempt is the simple and straightforward one, which is iterating over the list of orders and fetch them from Firebase. However, two main issues. Firstly, the create row in the table block is taking quite some time so I had to introduce a delay to somehow get the orders in detail because of firebase async calls. Secondly, whenever I navigate to another screen and start this one again although it deletes the remaining rows, it still doesn’t stop the async calls to the firebase which results in duplication of orders in the local orders list. Not perfect though, and sometimes the same behaviour as mentioned earlier and sometimes it is working fine.

The second attempt is to check the Tables if they have a match already, along with forcing a sync call to the firebase (only send another request if the current one is valid). For some reason it doesn’t fetch all orders (it just stops, I thought that there might have been an error and it just crashed after several iterations but I couldn’t find it yet).

Thirdly, as I am sure the create row in the table block is taking quite some time and most probably the behaviour is due to the async call to firebase with the delay in that block. I tried to firstly create rows in advance before fetching orders data from the Database, and then, later on, update them (by storing order Id to row ID in a variable like a map). Surprisingly this method is the worst as for some reason data is not stored in the correct row, maybe because of how the functions are built-in Thunkable or something else, I am not sure. but it is the worst approach so far.

Hope you can have a better idea of how things are implemented and that the idea and blocks are clear. And appreciate any help

1 Like

Thank you for your explanation.

If you feel the issue is caused by the asynchronous nature of the Firebase Get block then you can use the cloud variables instead as they are synchronous and should get you rid of this problem at once.

See this post for explanation and how to convert from one to the other

From the first image you shared Fetch Orders

  • You are using a stored variable this introduces delays
  • You are using list of values in .... this introduces delays
  • The image does not show the whole function and therefore it is not clear what is after the create row block

My advice is to create a new project that only reproduce the error you are facing and share it here so we can help. Your example project could use sample JSON block instead of the Realtime DB connection.

1 Like

Hi, There is nothing after the create row block, So the images shows the whole blocks actually.

Nevertheless, I have implemented a sample app that reproduces the issue, check it out:
https://x.thunkable.com/copy/49d3e35786727bf49650a73c6c5e343e

So it will fetch 6 rows, but if you refresh the Dataviewer (by dragging it down) you will see that not all 6 are there (the number varies each time). Mostly because of the delays, but introducing a timeout in my opinion will not solve the issue because it depends on the network speed and how much data is transferred and might result on no effect by the timeout (not for the this example as the data is small but generally speaking as a workaround solution).

1 Like

Dear @cassandra
@jane
@domhnallohanlon
@wei

I made a number of tests on the sample project provided by @darweeshworkqxl and could conclude that the create row block is providing false save information. The data is cached (somehow) and then flushed and only part of the rows are actually written to the table.

I made the same test on a google sheet and found All OK.

@codeswept ((see this as it relates to an issue you complained about))

3 Likes

Thanks @muneer - this is really helpful.

We’ll take a look and figure out what’s going on here.

Will keep you updated here as we learn more.

2 Likes

Temporarily, a workaround is to store the Data recursively.
Check the image here and the link to the implementation as well.
https://x.thunkable.com/copy/908baf428381445b9a043bc5270b3aad

@domhnallohanlon is there any update in here? because the workaround is slower.

1 Like

dear @darweeshworkqxl
Please see a better workaround version of your case.
https://x.thunkable.com/projectPage/6174ffbb20566a0011faf503

Also see my explanation of the workaround in another post.

1 Like

Thank you for your effort and time @muneer.
I would say it might not be better workaround (performance wise) as it introduces a delay and infinite loop. However, it might be easier for people to grasp who are not familiar with recursive calls for a function.

Nevertheless, I would say your documentation is better so people can understand it easier.

Have a nice day :slight_smile:

1 Like

Thank you for your comments.

The delay is necessary to give amble time for the create row to complete whatever it needs to do. It is worth to note that it is not an actual delay but a necessity due to storage speed. The trigger is in the create row block to end the delay. If you run it in a fast computer you will NOT notice the delay.

The other part (infinite loop) can be easily mitigated by maintaining a counter or a timer to break the loop when it takes too long.

Comparing the recursive approach with this approach, this method should be consuming the same time if not faster.