Firebase 电子邮件身份验证规则未按预期工作

Firebase email authentication with rules not working as expected

在管理屏幕中,我同时启用了电子邮件身份验证和匿名登录。 数据只有一个节点 - 你好:"World"

我的规则是

{
      "rules": {        
        ".read": "auth != null",
        //".read": true,
        ".write": true

      }
}

如果用户没有按照上述规则登录,那么你会得到 读取失败:权限被拒绝 这样就好了。

如果匿名用户登录,那么我可以看到值“{Hello=World”} 目前有效。

如果我使用电子邮件用户登录,我会收到错误消息:FirebaseError: Permission denied

onAuthenticate 确实触发了,我得到: 用户 ID:3c6ce912-a05a-49ed-ae68-8ec97d022303,提供商:密码

完整代码如下。我做错了什么?

import com.firebase.client.AuthData;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class FirebaseTest {

Firebase ref = new Firebase("https://<FIREBASE NAME>.firebaseio.com/");

public FirebaseTest() {

    //logonAnonymous(); //works
    logonEmail();  //permission denied

     showValues();         

     try {
         System.out.println("Waiting for input");               
     System.in.read();
    } catch (IOException ex) {
        Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private void logonAnonymous() {
    ref.authAnonymously(new Firebase.AuthResultHandler() {
        @Override
        public void onAuthenticated(AuthData authData) {
            // we've authenticated this session with your Firebase app
             System.out.println("User ID: " + authData.getUid() + ", Provider: " + authData.getProvider());
        }

        @Override
        public void onAuthenticationError(FirebaseError firebaseError) {
            // there was an error
            System.out.println("Anon user auth error " + firebaseError.toString());

        }
    });
}

private void logonEmail() {

    ref.authWithPassword("myuser@home.com", "secret", new Firebase.AuthResultHandler() {
        @Override
        public void onAuthenticated(AuthData authData) {
            System.out.println("User ID: " + authData.getUid() + ", Provider: " + authData.getProvider());
        }

        @Override
        public void onAuthenticationError(FirebaseError firebaseError) {
            // there was an error
        }
    });
}

public void showValues() {

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            System.out.println( " value -" + snapshot.getValue());
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            System.out.println("The read failed: " + firebaseError.getMessage());
        }
    });
}

}

我很确定您刚刚看到了电子邮件+密码身份验证异步发生这一事实的影响。

按此顺序:

logonEmail();
showValues();         

showValues() 执行时身份验证尚未完成。

异步排序的解决方案很简单,但最初非常不直观:您需要确保showValues()仅在身份验证成功后执行。

一个简单的方法:

private void logonEmail() {

    ref.authWithPassword("myuser@home.com", "secret", new Firebase.AuthResultHandler() {
        @Override
        public void onAuthenticated(AuthData authData) {
            System.out.println("User ID: " + authData.getUid() + ", Provider: " + authData.getProvider());

            // The user has been authenticated, so we can now safely call showValue()
            showValues();
        }

        @Override
        public void onAuthenticationError(FirebaseError firebaseError) {
            // there was an error
        }
    });
}