使用Firebase+Android设计签到/注册逻辑时遇到问题[英] Having Problems Designing Sign-In / Sign-Up Logic with Firebase + Android

本文是小编为大家收集整理的关于使用Firebase+Android设计签到/注册逻辑时遇到问题的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我使用Android/编程相对较新...我正在尝试设计一个使用Firebase作为后端的应用程序(尽管对于任何试图基于远程决定即时决定的应用程序,我遇到的问题都将存在数据).

我觉得有一种更聪明的方法可以做我想做的事情.

要求是(我在考虑问题的方式):

  • 设计一个新用户登录并注册的应用程序(两件单独的内容),但是该应用程序将不允许他们正确使用该应用程序,除非他们通过Firebase数据库控制台(由人手动)(手动)授权(手动).现有/批准的用户将绕过这些阶段.

所以...为了解决这个问题,我想:

  1. 当他们第一次打开应用程序时,如果他们没有登录,请向他们提供标志活动.

  2. 如果成功登录后,发现他们尚未注册,然后出示注册活动.

  3. 如果成功注册后,发现他们尚未批准,然后使用警报对话框退出应用程序,解释他们必须等待更长的时间才能批准.

听起来很简单...所以我们可以使用这样的mainactivity onResume()方法:

@Override
protected void onResume(){
    super.onResume();

    // if not signed in, go to signIn/Create account activity

    // (either we are signed in or we return from signin.java)

    // if not signedUP/registered, then we go to signUP/register activity

    // (either we are signed up or we return from register.java)

    //  is user admin-approved?  if not, then we exit.


}

但是,当我们尝试实施这些"检查"时,问题出现了.

您如何检查用户是否已经注册?我想,好吧,我们只能查询firebase数据库...例如:

  • 要找出用户是否已经注册,我们在firebase db的JSON树中检查了与用户ID签名的json树中的分支(键),然后我们知道他们已经注册了(因为注册活动本来可以创建此记录)

  • 要检查它们是否已批准,我们将检查一个字段,例如:

    '\firebase\user_id\isAllowed' = true. 
    

此字段默认情况下将设置为false,并且仅当管理员手动设置数据库中的值时,将设置为true.

但是,这些远程检查将需要时间来执行...并且结果是通过回调方法交付的...因此,我们如何"暂停" OnResume方法,以便它在继续之前等待结果? (我们可以在回调中"嵌套"回调:Firstcheck.onsuccess() { [Secondcheck.onsuccess() { [Thirdcheck.onsuccess() { // SUCCESS! }] } ] } ...但是这似乎是一个坏主意.

好吧...所以为什么不使用共享的偏好,而是让注册活动保存一个" user_progress"变量,例如1,这意味着他们已经完成了注册?这样,用户的进度将在本地存储,并且可以立即在onresume()逻辑中检查.

但是,这会产生一个新问题……那就是用户重新安装应用程序怎么办?然后,擦除了共享的偏好,现在相信它们没有注册...并错误地再次向他们展示注册活动.

我有针对这些个体问题的个人解决方案,但是结果是很难遵循代码的老鼠巢...

还有其他人遇到这种问题吗?我想在哪里出错?我觉得我正在接近它的根本不正确的方法...就像程序性与对象为导向...我想知道是否有人可以解决这个问题.

推荐答案

好吧...由于没有人回答,我仍然一直在研究这个问题,我最好的解决方案是:

在签名性中,当用户成功签名时,我将从共享的偏好中保存从firebase数据库中保存其datasnapshot(配置文件)的副本.这样,当他们以主进性返回onResume()时,它可以使用此快照来确定我需要的所有条件而无需涉及回调.随后,在注册活动中,我将在完成后更新本地快照.

我用新的发射器类ActionDecider替换了" MainAttivity".

actiondecider.onresume():

@Override
protected void onResume(){
    super.onResume();

    // TODO: do safetynet check here


    // (4) CONDITIONS :  HOW TO TELL :  WHAT TO DO
    // 
    // 1)not signed in : auth == null : load SignINActivity
    // 2)signed in, but not registered : snapshot == null : load SignUPActivity
    // 3)registered, but not approved : /userid/isAllowed == false : exit with dialog
    // 4)registered, and approved : /userid/isAllowed == true : continue as normal



    // if not signed in, go to signIn/Create account activity

        // user is sent to signIN which signs them in (or creates account), and saves a
        // datasnapshot of their db tree to shared prefs before returning here


    // (user is signed in)

    // CHECK: is user approved? (check the snapshot -- this is checked first because in 
    // most cases they will be approved, and this avoids an unnecessary extra check)

        // yes?  [exit] and load mainActivity. []

        // no?  CHECK:  is user signed up?

                // no?  load signUP-Activity   (signUP activity UPDATES datasnapshot when complete)

                // yes?  [exit] with dialog 

}

最佳解决方案?我对此表示怀疑.但是...随时让我知道一种更好的方法.

本文地址:https://www.itbaoku.cn/post/627334.html

问题描述

I'm relatively new with Android/programming... I'm trying to design an app that uses Firebase as the backend (although the problems I am having would exist for any app that tries to make immediate decisions based on remote data).

I feel like there is a smarter way to do what I'm trying to do.

The requirements are (the way I'm thinking about problem):

  • Design an app where new users sign in and register (two separate things), but the app will not allow them to use the app properly unless they have been expicitly (manually) authorized by a human via the Firebase database console. Existing/approved users will bypass these stages.

So... to solve this, I have thought:

  1. When they first open the app, if they are not signed in, present them with a SignIn Activity.

  2. If, upon successful sign-in, it is found they have not yet registered, then present a registration Activity.

  3. If upon successful registration, it is found that they are not yet admin-approved, then exit the app with an alert dialog explaining they must wait longer for approval.

Sounds simple... so we could just have a MainActivity onResume() method like this:

@Override
protected void onResume(){
    super.onResume();

    // if not signed in, go to signIn/Create account activity

    // (either we are signed in or we return from signin.java)

    // if not signedUP/registered, then we go to signUP/register activity

    // (either we are signed up or we return from register.java)

    //  is user admin-approved?  if not, then we exit.


}

But the problems arise when we try to implement these "checks."

How do you check whether a user has already registered? I thought, well, we can just query the Firebase database... for example:

  • To find out if a user has already registered, we check for a branch (key) in the JSON tree of the Firebase DB that matches the signed in userID, then we know they have registered (because the registration activity would have created this record already)

  • To check whether they are admin-approved, we would check for a field such as:

    '\firebase\user_id\isAllowed' = true. 
    

This field would be set to false by default and set to true only if an admin manually sets the value in the database.

But these sort of remote checks will take time to execute... and the results are delivered via callback methods... so how can we "pause" the onresume method so that it waits for the result before continuing?? (we could 'nest' callbacks within callbacks: Firstcheck.onsuccess() { [Secondcheck.onsuccess() { [Thirdcheck.onsuccess() { // SUCCESS! }] } ] } ... but this seems like a bad idea.

Alright... so why not use shared preferences instead, and have the registration activity save a "user_progress" variable such as 1, meaning that they have completed the registration? This way the user's progress would be stored locally and could be immediately checked in the onresume() logic.

But then this creates a new problem... that is what if the user re-installs the app? then the shared preferences are wiped and it would now believe that they are not registered... and mistakenly present them with the registration activity again.

I have individual solutions for these individual problems, but what results is a rat's nest of hard to follow code...

Has anyone else been stuck with this kind of problem? Where am I going wrong in my thinking? I feel like there is a fundamentally incorrect way that I'm approaching it... like procedural vs object oriented... and I'm wondering if anyone can address that.

推荐答案

Well... since nobody has answered yet, I've still been working on this, and my best solution is:

In the SignINActivity, when the user is successfully signed in, I will save a copy of their datasnapshot (profile) from the Firebase database in Shared Preferences. That way, when they return to the onResume() in MainActivity, it can use this snapshot to determine all the conditions I need without callbacks being involved. Subsequently, in signUPActivity, I will update the local snapshot when that is completed, also.

I have replaced 'MainActivity' with a new launcher class, ActionDecider.

ActionDecider.onResume() :

@Override
protected void onResume(){
    super.onResume();

    // TODO: do safetynet check here


    // (4) CONDITIONS :  HOW TO TELL :  WHAT TO DO
    // 
    // 1)not signed in : auth == null : load SignINActivity
    // 2)signed in, but not registered : snapshot == null : load SignUPActivity
    // 3)registered, but not approved : /userid/isAllowed == false : exit with dialog
    // 4)registered, and approved : /userid/isAllowed == true : continue as normal



    // if not signed in, go to signIn/Create account activity

        // user is sent to signIN which signs them in (or creates account), and saves a
        // datasnapshot of their db tree to shared prefs before returning here


    // (user is signed in)

    // CHECK: is user approved? (check the snapshot -- this is checked first because in 
    // most cases they will be approved, and this avoids an unnecessary extra check)

        // yes?  [exit] and load mainActivity. []

        // no?  CHECK:  is user signed up?

                // no?  load signUP-Activity   (signUP activity UPDATES datasnapshot when complete)

                // yes?  [exit] with dialog 

}

Best solution? I doubt it. But... feel free to let me know a better approach.