【问题标题】:Firebase database - force read value on demandFirebase 数据库 - 按需强制读取值
【发布时间】:2018-02-13 19:35:31
【问题描述】:

我在强制从 Firebase 实时数据库读取值时遇到问题。我的申请流程:

SplashActivity->LoginActivity->MainActivity。当用户登录时,SplashActivity 和 LoginActivity 不存在。当用户注销时,主要活动完成并再次创建 LoginActivity。

在 MainActivity onCreate 事件中,从 Firebase 中检索有趣的数据:

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("appVariant");

    myRef.child("stable").addListenerForSingleValueEvent(new ValueEventListener()
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot)
        {
            AppVariant v = dataSnapshot.getValue(AppVariant.class);
            Log.d(BuildConfig.APPLICATION_ID, String.format("Data change:  %s", v.toString()));
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });

它工作正常,但只是第一次创建MainActivity。如果我注销(所以 MainActivity 已完成),然后再次登录(MainActivity 重新创建),onDataChanged 永远不会再次触发。

如何在不重新启动应用程序的情况下强制再次获取子值?我需要按需检索数据,每次用户登录后,一次(无需监控任何更改)。这可能吗?

【问题讨论】:

  • 如果您需要在每次用户登录时加载一次相同的数据,则需要在每次用户登录时附加相同的监听器。
  • 你的意思是监听器不应该被重新创建,它应该存在于活动生命周期之外吗?
  • 我认为您误解了 Activity 触发的生命周期方法。 onCreate 仅在最初创建活动时触发。如果要在每次激活活动时加载数据,请将代码放入onStart()onResume()。请参阅developer.android.com/guide/components/activities/… 以获得良好的图表
  • 你错了。我已经调试过了,我确定addListenerForSingleValueEvent 被再次调用,但不是onDataChange。请注意,在注销时,MainActivity 完成(通过调用 fhinish 方法)并启动新的 LoginActiviwy 实例。然后,在用户登录后,LoginActivity 启动新的MainActivity 实例,所以onCreate 将再次被触发。
  • 在这种情况下,您可能会收到“权限被拒绝”。实施onCancelled 来捕捉它,例如public void onCancelled(DatabaseError databaseError) { throw databaseError.toException(); }

标签: java android firebase firebase-realtime-database


【解决方案1】:

这不是身份验证过程的正常流程。如果您有两个不同的活动(让我们省略 SplashActivity),例如 LoginActivityMainActivity,您应该考虑执行以下操作:

  1. 将您的 LoginActivity 作为您的应用程序在 AndroidManifest.xml 文件中启动的默认活动
  2. 将 MainActivity 添加为另一个 Activity
  3. 在 LoginActivity 中添加身份验证逻辑。
  4. 在您的 LoginActivity 中创建一个authStateListener 以检查用户身份验证的状态。如果 firebaseUser != null 则将用户重定向到 MainActivity。
  5. 也在您的 MainActivity 中创建一个authStateListener 以检查用户身份验证的状态。如果是firebaseUser == null,则将用户重定向到 LoginActivity。

通过身份验证后,您可以使用侦听器,而不必担心您的活动会重新启动。

就是这样。为了更好地理解,如果您有时间,请查看我的tutorials 之一,其中我已逐步解释,所有身份验证过程使用两个不同的活动。

【讨论】:

  • 我的流程和你的差不多。唯一的区别:我确实需要在启动MainActivity 之前完成LoginActivity,因为MainActivity 需要在用户登录后位于堆栈顶部。否则,单击返回按钮时,会显示 LoginActivity,这是错误的。注销后也是如此:需要完成主要活动并启动 LoginActivity,否则,当用户单击返回按钮时,将显示以前的 MainAcitivity 实例。身份验证逻辑在 LoginActivity 内部。您能否更具体地说明我的方法有什么问题?
  • P.S.默认活动是 SplashActivity,它启动 LoginActivity,然后 LoginActity(成功登录后)启动 MainActivity。
  • 正如弗兰克所说,这完全是关于 Activity 的生命周期方法。实现onCancelled(DatabaseError databaseError) 始终是一个好习惯,因为它可以为您提供确切的错误。
  • 对不起,我没有回复,感谢您的帮助。我没有回应的原因是到目前为止我无法检查它(许多项目,这个需要暂停一段时间,因为优先级)。我将很快再次检查所有内容,然后接受您的回答或最终提供更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多