Skip to main content

Cloud Firestore API issue with listeners, Python/Kivy jnius/jnius_proxy.pxi error on android

I have a problem that I've been stuck for 2 weeks trying to understand and solve. In the application I have a RecycleView, so I also have a system that reads and adds a listener(stream) to a Cloud Firestore document, when data changes in the database it is automatically placed in a DictProperty. But the real problem is in RecycleView, when database data is changed, RecycleView is affected for some reason and an error is returned:

Traceback (most recent call last):
  File "jnius/jnius_proxy.pxi", line 156, in jnius.jnius.invoke0
  File "jnius/jnius_proxy.pxi", line 124, in jnius.jnius.py_invoke0
AttributeError: 'list' object has no attribute 'invoke'

List refers to RecycleView's data attribute

E às vezes retornava esse outro error:

Traceback (most recent call last):
  File "jnius/jnius_proxy.pxi", line 156, in jnius.jnius.invoke0
  File "jnius/jnius_proxy.pxi", line 124, in jnius.jnius.py_invoke0
AttributeError: 'kivy.properties.PropertyStorage' object has no attribute 'invoke'

I have no idea how to solve this, and the reason for this error. Please if anyone can help me. I'm using the cloud firestore API.

Eu sei que a melhor solução é migrar para java, mas estou tentando me familiarizar com o android com python primeiro. Pretendo aprender java no futuro.

main.py

from kivy.properties import DictProperty, BooleanProperty
from kivy.uix.screenmanager import ScreenManager
from kivymd.app import MDApp

class WindowManager(ScreenManager):
    pass

class MyApp(MDApp):
    profile_data = DictProperty(rebind=True)
    registered = BooleanProperty(False)
    loaded_data = BooleanProperty(False)    

    def __init__(self, **kwargs):
        super(MyApp, self).__init__(**kwargs)
        self.sm = WindowManager()

    def build(self):
        return self.sm

    def on_start(self):
        import android_db
        self.bind(profile_data=self.check_profile_data)
        android_db.read_firebase_data("collection", "person")
        return super().on_start()

    def check_profile_data(self, *args):
        if self.profile_data == {}:
            self.registered = False
        elif len(self.profile_data) >= 7:
            self.registered = True

if __name__ == "__main__":
    MyApp().run()

To do the java part I followed this tutorial: https://www.youtube.com/watch?v=aZGXJXzGLhI&t=20s

android_db.py

from jnius import autoclass, cast, PythonJavaClass, java_method
from kivy.app import App

PythonActivity = autoclass("org.kivy.android.PythonActivity")
currentActivity = cast("android.app.Activity", PythonActivity.mActivity)
context = cast("android.content.Context", currentActivity.getApplicationContext())

FirebaseApp = autoclass("com.google.firebase.FirebaseApp")
FirebaseFirestore = autoclass("com.google.firebase.firestore.FirebaseFirestore")
FirebaseApp.initializeApp(context)

db = FirebaseFirestore.getInstance()
APP_INSTANCE = App.get_running_app()

def read_firebase_data(collection:str, document:str):
    ref = db.collection(collection).document(document).get()
    ref.addOnSuccessListener(DataSuccessListener())

listener = None
def stream_firebase_data(collection:str, document:str):
    global listener
    ref = db.collection(collection).document(document)
    if listener is None:
        listener = ref.addSnapshotListener(DataSnapshotListener())

class DataSuccessListener(PythonJavaClass):
    __javainterfaces__ = ["com/google/android/gms/tasks/OnSuccessListener"]
    __javacontext__ = "app"

    @java_method("(Ljava/lang/Object;)V")
    def onSuccess(self, doc):
        data = doc.getData()
        for key in data.keySet():
            APP_INSTANCE.profile_data[key] = data.get(key)
        print(APP_INSTANCE.profile_data)
        stream_firebase_data("collection", doc.id)

class DataSnapshotListener(PythonJavaClass):
    __javainterfaces__ = ["com/google/firebase/firestore/EventListener"]
    __javacontext__ = "app"

    @java_method('(Ljava/lang/Object;Lcom/google/firebase/firestore/FirebaseFirestoreException;)V')
    def onEvent(self, doc, error):
        try:
            data = doc.getData()
            for key in data.keySet():
                APP_INSTANCE.profile_data[key] = data.get(key)
            print(APP_INSTANCE.profile_data)
            APP_INSTANCE.loaded_data = True
        except Exception as e:print(e)

RecycleView.py

from kivy.uix.recycleview import RecycleView

class MyRecycleView(RecycleView):
    pass

RecycleView.kv

<MyRecycleView>:
    viewclass: "MD2Card"
    effect_cls: "ScrollEffect"
    RecycleBoxLayout:
        default_size: None, None
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        spacing: dp(25)
        padding: [0, dp(5), 0, dp(10)]

Location I'm using MyRecycleView

Screen:
    name: "peq"
    MyRecycleView:
        id: small

Screen:
    name: "med"
    MyRecycleView:
        id: mid

Screen:
    name: "gra"
    MyRecycleView:
        id: big

In main.py there is load_data, it is used for when the Cloud Firestore data is loaded and added to the profile_data, load the data attribute of the RecycleView

When the screen containing the RecyclerView is loaded which is before the read_firebase_data function in the main.py file in on_start, this function is done:

def update(self, **kwargs):
        self.app = App.get_running_app()
        self.app.bind(loaded_data=self.testt)

    @mainthread
    def testt(self, *ars):
        if self.app.loaded_data:
            self.ids.small.data = [
            {
                "size_hint":(.75, None),
                "pos_hint":{"center_x":.5},
                "md_bg_color":get_color_from_hex("#8758b3")
            } for _ in range(20)
        ]

This function works great, the data is put in the RecycleView, but when the data is changed an error is returned:

AttributeError: 'list' object has no attribute 'invoke'

Please if anyone can help me I will be very grateful, and I'm sorry if my explanation was not very good. Thank you in advance for your attention.



source https://stackoverflow.com/questions/73178696/cloud-firestore-api-issue-with-listeners-python-kivy-jnius-jnius-proxy-pxi-erro

Comments

Popular posts from this blog

Prop `className` did not match in next js app

I have written a sample code ( Github Link here ). this is a simple next js app, but giving me error when I refresh the page. This seems to be the common problem and I tried the fix provided in the internet but does not seem to fix my issue. The error is Warning: Prop className did not match. Server: "MuiBox-root MuiBox-root-1" Client: "MuiBox-root MuiBox-root-2". Did changes for _document.js, modified _app.js as mentioned in official website and solutions in stackoverflow. but nothing seems to work. Could someone take a look and help me whats wrong with the code? Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console