CloudDB does not generate DataChanged event

CloudDB does not generate DataChanged event after upgrading from Android 9 to 10

Compilado: February 3 2020 Versão: nb182
Use Companion: 2.57 or 2.57u

I can confirm this behaviour in Companion 257u

DataChanged returns neither tag nor value.

Get/Got Value works OK

I can also confirm the issue. I have a fix, unfortunately it means a new Companion. Stay tuned for more info.

We have a fix, it is currently on ai2-test. You can download Companion version 2.57t1 from ai2-test and it will work properly even with ai2 and code.appinventor.mit.edu. However only apps packaged on ai2-test will work properly.

We hope to deploy the new Companion and system (nb182a) tomorrow (Wednesday).

The fix is out. You can download MIT AI2 Companion version 2.57a from Google Play or download 2.57au from ai2.appinventor.mit.edu. Any apps that use CloudDB or FirebaseDB that were packaged with nb182 should be re-packaged with nb182a

code.appinventor.mit.edu will be updated a little later today.

DataChanged not yet working for me for CloudDB.
Works fine for FirebaseDB.

What is not yet working when using the CloudDB Sarvesh?

The CloudDB.DataChanged event works fine for me. The event fires and is aware of both tag and value.

I use

  • the emulator
  • the MIT CloudDB default server.
  • Companion 2.57a

What does your DataChanged block look like? Are you using this with your own Redis server or the MIT default server? Are you using Companion or compiling and running the apk?

Steve, the CloudDB.DataChange isn’t working for me.

I used

  • apk built on MIT server
  • redis server from redislab, free subscription
  • Phone running Android 6 (Could that be something related to the issue?)

My block looks like this -
dataChangedBlock

As a work around, I’m using a clock which triggers GetValue after a specific interval and that works fine. But I should really be using the DataChanged block rather than adding this processing overhead.

Your issue could be related to the redis’s server you use. Free subscriptions (Cloud Essentials) does not have all the features of Cloud Pro. That might be the issue . Have you tried the MIT default server with your ‘data’? I have no idea whether it mimics Essentials or Pro and how it responds to the fix MIT recently made to DataChanged. What works on the MIT server might not work on the redis server you use.

I built the apk for my CloudDB and ran it on my tablet (Android 8.1) as an app. The DataChanged works fine in my compiled app.

Your issue could be related to what is contained in ‘data’. If what is stored is a large amount of information, setting LabelGotVal.Text with the ‘value’ might be a timing issue. You might need to process this appropriately with a Clock. You ‘using a clock which triggers GetValue after a specific interval and that works fine.’ is telling.

When you say ‘isn’t working for me’ isn’t a lot of help. One needs to know something about the volume of information you expect to appear instantaneously on your app to debug. You do not explain whether the DataChanged event ‘fires’ … you might add a Label set to tag + value and code it outside an if loop. What happens? Is the DataChanged event firing or you are just not receiving the instantaneous update?

Thanks for the heads up Steve!

I performed a debug again and found that the DataChanged sometimes triggers, but most of the times does not trigger.
testTrigblocks

I’d check it on MIT servers and post the results.

Okay, here’s an update.

For CloudDB, the DataChanged block is triggered if I update the database from within the AI app.
However, it does not trigger if I update the database remotely, without using the app.

I cannot really test whether it works with MIT’s default DB server, as I do not have url or cli access to the DEFAULT server to test the remote update.

EDIT: Is it so that the DataChanged block in CloudDB is triggered only when the Redis server responds to a PUT request? In other words, is it not triggering on changes globally?

I have tested this with my redis labs setup and can confirm that if I set a value outside of the app, it is not seen by the dataChanged event in the app.

However it does work if two different devices are using the same app.

I did set up a local Redis server and tested it.
(Thanks @TIMAI2 for the tutorial! https://groups.google.com/forum/#!msg/mitappinventortest/GPtZN2viC3E/Cna0GhAeEgAJ)

I got same results as yours on my local redis server. The dataChanged procedure isn’t firing when the database is not updated from the app.
So it seems the issue is not with redislab servers.
@ewpatton Is the issue related to the CloudDB AI component?

I think it’d be great if works just like Firebase, because the open source Redis is a good alternative to Firebase. Also, as @SteveJG pointed it out in another post, the current Firebase code used with AI is deprecated.

You must issue at least one GetValue request before DataChanged will fire, and it will only fire for keys originally requested. It also only responds to a subset of the key hierarchy that the app would respond to, not to arbitrary key changes in the Redis database. Importantly, CloudDB is not a push notification service. Once you start making changes from external services, you need to be aware of the constraints around what DataChanged expects, otherwise it will not work.

I tried putting both GetValue and StoreValue blocks in the screen initialize routine. Still doesn’t fire if updated externally.

Could Redis pub/sub be implemented in the component?

How are you updating externally? As far as CloudDB is concerned, all values are stringified JSON structures. Also, there’s a bug in 2.57 around CloudDB DataChanged, so if you’re using that version of the companion you should update to 2.57a.

I am updating the key values using arduino with arduino-redis library.
I decoded the key naming pattern using redis cli and updating the values using the same structures.
When I read the values using a GetValue block anywhere, say within a clock , the values are read perfectly. However, the DataChanged block never fires if I update the values externally.

I also tested it with updating the key values using redis-cli. For example
redis-cli > set "x:val" "\"50,60,70\""
Here “x” is the projectID set in App Inventor’s CloudDB component and “val” is the key within the app. So the “projectID:key” is the pattern.
Same results. GetValue works, but DataChanged doesn’t trigger.

I’m not using companion. I’m using the built apk.

You’re violating CloudDB’s expectations so the behavior is naturally undefined., namely that the CloudDB component serializes all values as JSON before sending them to the server. 50,60,70 is not valid JSON so it will not decode correctly. The fact that GetValue works is just a quirk because it falls back to the unparsed version. Update your value to either be a string (by wrapping it in an additional set of double quotes) or by wrapping it in square brackets to turn it into an array.

I was already adding the quotes, had forgotten to add in the above example.
My cli command was - set "x:val" "\"50,60,70\""
Still DataChanged doesn’t get triggered.

Now I tried adding square brackets like "[50,60,70]" to make it a list.
My cli command was - set "x:val" "[50,60,70]"
Still DataChanged isn’t triggering.

Ialso tried using “|” as the separator for string data.
My cli command was - set "x:val" "\"50|60|70\""
Still DataChanged isn’t triggering.

Do you see any errors reported by CloudDB if you use adb logcat to monitor your app?