Behaviour of RT Database

Hello everyone

I’m currently working on a school project and wanted to try out backendless. While implementing the application I encounter multiple strange behaviours.

  1. I’m not receiving any UPDATE or CREATE callbacks from the RT database. DELETE works though. I tested this by creating, updating or deleting entries in the data browser and checked If the debugger hits the breakpoint

  2. I’m not receiving ANY callbacks when the user deletes, updates or creates its own entry. Unlike to the previous case, I manipulated the data inside the implementation and this does not seem to trigger the events. None of them

Case 1 strikes me as a bug and 2 as an undocumented behaviour which I would like to have clarified.

I’m using Android 29 with Kotlin, backendless 5.7.1 in free tier, iosocket 1.0.0 and application key is AFF4F4C2-C72C-5572-FFCB-7103E05B2600

Best regards and thanks for your replies

Hi @Matthieu_Riolo,

Can you provide code samples which show how you register your callbacks?

Regards, Andriy

if i may
check the user permissions. make sure he have the correct access rule.

Oh man, while posting I noticed my mistake. I can confirm, both cases work exactly as expected :slight_smile: sorry for the trouble.

I might ask though for clarification concerning: “Listeners per real-time connection”. How exactly is this meant? Let’s say I have 2 tables and I want to listen for all changes for both of them, would this mean I have 6 listeners per connection ? Or is a connection understood as 1 access to a table?

the stripped down code looks like this

/*
* This class can used together with backendless
* */
class BackendlessLiveData<DATA : BackendlessIdentifier>(
    private val converter: ConverterInterface<DATA>,
    private val dataStore: IDataStore<Map<Any?, Any?>>
) : LiveData<List<DATA>>() {
    private val data = mutableMapOf<String, DATA>()
    private val changeHandler = object : AsyncCallback<Map<Any?, Any?>>{
        override fun handleFault(fault: BackendlessFault?) {
            Log.e(TAG, "Failed to retrieve update or creation: $fault")
        }

        override fun handleResponse(response: Map<Any?, Any?>?) {
            response?.let {
                val item = converter.toObject(response)
                data[item.identifier()] = item
                updateValues()
            }
        }
    }

    private val deleteHandler = object : AsyncCallback<Map<Any?, Any?>>{
        override fun handleFault(fault: BackendlessFault?) {
            Log.e(TAG, "Failed to retrieve delete: $fault")
        }

        override fun handleResponse(response: Map<Any?, Any?>?) {
            response?.let {
                val item = converter.toObject(response)
                data.remove(item.identifier())
                updateValues()
            }
        }
    }

    init {
        dataStore.find(query, object : AsyncCallback<List<Map<Any?, Any?>>> {
            override fun handleFault(fault: BackendlessFault?) {
                Log.e(TAG, "Failed to retrieve data: $fault")
            }

            override fun handleResponse(response: List<Map<Any?, Any?>>?) {
                response?.let {
                    for (mappedData in response) {
                        val item = converter.toObject(mappedData)
                        data[item.identifier()] = item
                    }

                    updateValues()
                }
            }
        })
    }

    override fun onActive() {
        super.onActive()
        //todo: update and create listener do not work (but delete does...)
        dataStore.rt().addUpdateListener(changeHandler)
        dataStore.rt().addCreateListener(changeHandler)
        dataStore.rt().addDeleteListener(deleteHandler)
    }

    override fun onInactive() {
        super.onInactive()
        if (!hasActiveObservers()) {
            /* TODO: not working properly?
            dataStore.rt().removeUpdateListener(changeHandler)
            dataStore.rt().removeCreateListener(changeHandler)
            dataStore.rt().removeDeleteListener(deleteHandler)*/
        }
    }

private fun updateValues() {
        //my bug!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //values = LinkedList(data.values)
        postValue(LinkedList(data.values))
    }
}

@Matthieu_Riolo,
it is nice to hear that everething works as expected :grinning:

About your question related to “Listeners per real-time connection”. SDK for your app will open single socket connection and all RT events will go over it. In your case all 6 listeners will use same connection.

Regards, Andriy

@Matthieu_Riolo and keep in mind you have a limit of 30 listeners for a single client connection as i have read in the forum.

30? According to the pricing table it’s 5 per connection for the free tier. I would be very pleased if it were 30 because 5 would mean that I have to restrict myself heavely

i think its for the paid plans not the free tier :slight_smile:

Listeners per real-time connection
FREE: 5
DEVELOPER: 10
CLOUD 9: 30
CLOUD 99: 50

You are correct.
30 listeners are for “Cloud 9” plan.
All limitations of plans listed here: https://backendless.com/pricing/backendless-cloud/#comparison

Regards, Andriy