如何在Android中使用Livedata和ViewModel不断更新Firebase实时数据库的查询

发布于 2025-02-10 23:31:41 字数 4258 浏览 1 评论 0原文

我将Firebase实时数据库和Livedata与Android中的ViewModel一起使用,我想不断更新查询。

这是ViewModel类:

public class ViewModel_MainActivity extends ViewModel {


    /*
    LiveData with Database query for the Firebase node "Ratings"
    */

    private static long currentTimeMillisRating = System.currentTimeMillis();
    private static double pastMinuteForDisplayingRatings = 1;
    private static long pastTimeMillisRatings = System.currentTimeMillis() - (long) (pastMinuteForDisplayingRatings * 60 * 60 * 1000);


    private static final Query QUERY_RATINGS =
            FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference().child(DB_SQLite_Firebase_Entries.FIREBASE_NODE_RATINGS).orderByChild(DB_SQLite_Firebase_Entries.FIREBASE_RATINGDATEINMILLISECONDS).endAt(pastTimeMillisRatings);


    private final LiveData_FirebaseRating liveData_firebaseRating = new LiveData_FirebaseRating(QUERY_RATINGS);

    @NonNull
    public LiveData_FirebaseRating getDataSnapshotLiveData_FirebaseRating() {
        Log.e("LogTag_ViMo", "pastTimeMillisRatings: " + pastTimeMillisRatings);
        return liveData_firebaseRating;
    }


}

这是Livedata类:

public class LiveData_FirebaseRating extends LiveData<DataSnapshot> {
    private static final String LOG_TAG = "LiveData_FirebaseRating";

    private Query query;
    private final LiveData_FirebaseRating.MyValueEventListener listener = new LiveData_FirebaseRating.MyValueEventListener();

    DataSnapshot currentDataSnapShotFromFirebase;

    public LiveData_FirebaseRating(Query query) {
        this.query = query;
    }

    public LiveData_FirebaseRating(DatabaseReference ref) {
        this.query = ref;
    }

    public void changeQuery(Query newQuery) {
        this.query = newQuery;
    }

    public DataSnapshot getCurrentDataSnapShotFromFirebase() {
        return currentDataSnapShotFromFirebase;
    }

    public void setCurrentDataSnapShotFromFirebase(DataSnapshot currentDataSnapShotFromFirebase) {
        this.currentDataSnapShotFromFirebase = currentDataSnapShotFromFirebase;
    }

    @Override
    protected void onActive() {
        Log.d(LOG_TAG, "onActive");
        query.addValueEventListener(listener);
    }

    @Override
    protected void onInactive() {
        Log.d(LOG_TAG, "onInactive");
        query.removeEventListener(listener);
    }

    private class MyValueEventListener implements ValueEventListener {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {


            setValue(dataSnapshot);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(LOG_TAG, "Can't listen to query " + query, databaseError.toException());
        }
    }
}

这是创建和观察实时数据和视图模型的主要活动的一部分:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
       
        /*
        Initiate View Model with LiveData for Firebase
         */



        rootRef_Firebase = FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference();
        viewModel = new ViewModelProvider(this).get(ViewModel_MainActivity.class);

        liveData_firebaseRating = viewModel.getDataSnapshotLiveData_FirebaseRating();
        liveData_firebaseRating.observe(this, new Observer<DataSnapshot>() {

            @Override
            public void onChanged(@Nullable DataSnapshot dataSnapshot) {
                liveData_firebaseRating.setCurrentDataSnapShotFromFirebase(dataSnapshot);
                if(liveData_firebaseRating.getCurrentDataSnapShotFromFirebase()!=null) {
                    //Do something with the dataSnapshot of the query
                }
            }// end onChange
        }); //end observe



    }

因此,我的问题在于QUERY_RATINGS query_ratings < /代码>在类viewModel_mainActivity中。我想要的是从firebase_node_ratings中返回所有节点,其在属性firebase_ratingdateinmilliseconds年龄大于1分钟(这意味着该条目是在当前时间至少1分钟创建的投币口)。我该怎么做才能总是得到这些节点?

I use Firebase Realtime Database and LiveData with ViewModel in Android and I would like to constantly update the query.

Here is the ViewModel class:

public class ViewModel_MainActivity extends ViewModel {


    /*
    LiveData with Database query for the Firebase node "Ratings"
    */

    private static long currentTimeMillisRating = System.currentTimeMillis();
    private static double pastMinuteForDisplayingRatings = 1;
    private static long pastTimeMillisRatings = System.currentTimeMillis() - (long) (pastMinuteForDisplayingRatings * 60 * 60 * 1000);


    private static final Query QUERY_RATINGS =
            FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference().child(DB_SQLite_Firebase_Entries.FIREBASE_NODE_RATINGS).orderByChild(DB_SQLite_Firebase_Entries.FIREBASE_RATINGDATEINMILLISECONDS).endAt(pastTimeMillisRatings);


    private final LiveData_FirebaseRating liveData_firebaseRating = new LiveData_FirebaseRating(QUERY_RATINGS);

    @NonNull
    public LiveData_FirebaseRating getDataSnapshotLiveData_FirebaseRating() {
        Log.e("LogTag_ViMo", "pastTimeMillisRatings: " + pastTimeMillisRatings);
        return liveData_firebaseRating;
    }


}

Here is the LiveData class:

public class LiveData_FirebaseRating extends LiveData<DataSnapshot> {
    private static final String LOG_TAG = "LiveData_FirebaseRating";

    private Query query;
    private final LiveData_FirebaseRating.MyValueEventListener listener = new LiveData_FirebaseRating.MyValueEventListener();

    DataSnapshot currentDataSnapShotFromFirebase;

    public LiveData_FirebaseRating(Query query) {
        this.query = query;
    }

    public LiveData_FirebaseRating(DatabaseReference ref) {
        this.query = ref;
    }

    public void changeQuery(Query newQuery) {
        this.query = newQuery;
    }

    public DataSnapshot getCurrentDataSnapShotFromFirebase() {
        return currentDataSnapShotFromFirebase;
    }

    public void setCurrentDataSnapShotFromFirebase(DataSnapshot currentDataSnapShotFromFirebase) {
        this.currentDataSnapShotFromFirebase = currentDataSnapShotFromFirebase;
    }

    @Override
    protected void onActive() {
        Log.d(LOG_TAG, "onActive");
        query.addValueEventListener(listener);
    }

    @Override
    protected void onInactive() {
        Log.d(LOG_TAG, "onInactive");
        query.removeEventListener(listener);
    }

    private class MyValueEventListener implements ValueEventListener {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {


            setValue(dataSnapshot);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(LOG_TAG, "Can't listen to query " + query, databaseError.toException());
        }
    }
}

And here is the part of the main activity, where the live data and view model are created and observed:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
       
        /*
        Initiate View Model with LiveData for Firebase
         */



        rootRef_Firebase = FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference();
        viewModel = new ViewModelProvider(this).get(ViewModel_MainActivity.class);

        liveData_firebaseRating = viewModel.getDataSnapshotLiveData_FirebaseRating();
        liveData_firebaseRating.observe(this, new Observer<DataSnapshot>() {

            @Override
            public void onChanged(@Nullable DataSnapshot dataSnapshot) {
                liveData_firebaseRating.setCurrentDataSnapShotFromFirebase(dataSnapshot);
                if(liveData_firebaseRating.getCurrentDataSnapShotFromFirebase()!=null) {
                    //Do something with the dataSnapshot of the query
                }
            }// end onChange
        }); //end observe



    }

So my problem lies in the non-updating of the QUERY_RATINGSin the class ViewModel_MainActivity. What I want is to return all the nodes from the FIREBASE_NODE_RATINGS whose at attribute FIREBASE_RATINGDATEINMILLISECONDS is older than 1 Minute (meaning that the entry was created at least 1 Minute before the current time slot). How can I do that such that I always get these nodes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最近可好 2025-02-17 23:31:41

firebase 查询对象是不可变的,它们的参数为固定值。因此,无法更新现有查询,也没有自动更新的“一分钟前”值。

我可以快速思考的选项:

  • 经常创建一个新的查询以捕获新的全范围相关节点。
  • 经常创建一个新的查询以捕获仅新的节点(通过组合startatendat),并将它们与您已经拥有的结果合并。
  • 从查询中删除条件,然后在应用程序代码中执行过滤。

根据我所知道的,我可能会从第三个选项开始,因为这似乎是最简单的。

Firebase Query objects are immutable, and their parameters are fixed values. So there is no way to update the existing query, nor is there a "one minute ago" value that automatically updates.

The options I can quickly think off:

  • Create a new query frequently to capture the new full range of relevant nodes.
  • Create a new query frequently to capture only the new nodes (by combining startAt and endAt) and merge them with the results you already have.
  • Remove the condition from the query, and perform the filtering in your application code.

Based on what I know, I'd probably start with the third option as it seems the simplest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文