【问题标题】:Firebase Realtime Database - storing multiple nodes from user inputsFirebase 实时数据库 - 存储来自用户输入的多个节点
【发布时间】:2020-04-19 09:28:17
【问题描述】:

我是 Firebase 和 android studio 的新手,我正在尝试让多个节点保存在 Firebase 中,我有一个节点可以保存给“用户”,但我需要另一个节点来保存“预算”类别节省。最初我认为我的 OnClickListener 存在问题,但经过检查,它工作正常。 这是在我的注册中发送用户数据的代码:

 private void sendUserData(){
        String UserID = firebaseAuth.getUid();
        RegDB regDB = new RegDB(emailDb, nameDb, passwordDb);
        mDatabase.child("Users").child(UserID).setValue(regDB);
    }

这是在我的预算页面中发送用户数据的代码:

 private void sendUserData() {
        String UserID = firebaseAuth.getUid();
        CategoriesDB catDb = new CategoriesDB(travel_budget, entertainment_budget, fitness_budget, beauty_budget, clothes_budget, holiday_budget, food_budget, mobile_budget);
        mDatabase.child("Users").child(UserID).child("Categories").setValue(catDb);
    }

尽管 Firebase 为每个注册的人分配了一个唯一的用户 ID,并且此 ID 存储在实时数据库和身份验证中,但当我尝试输入预算时,我不断收到此错误:

java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()

作为参考,这是我的注册页面的 OnClickListener:

button_Upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (validate()) {
                    String emailDb = email.getText().toString().trim();
                    String passwordDb = password.getText().toString().trim();

                    firebaseAuth.createUserWithEmailAndPassword(emailDb, passwordDb).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            if (task.isSuccessful()) {
                                sendUserData();
                                firebaseAuth.signOut();
                                Toast.makeText(Register.this, "Successfully Registered!", Toast.LENGTH_SHORT).show();
                                finish();
                                startActivity(new Intent(Register.this, Menu.class));
                            } else {
                                Toast.makeText(Register.this, "Registration Failed.", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });

也是我的预算页面的 OnClickListener:

btn_subCat.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(validate()){
                sendUserData();
                Toast.makeText(Categories.this, "Completed!", Toast.LENGTH_LONG).show();
                finish();
                startActivity(new Intent(Categories.this, Menu.class ));
            }else{
                Toast.makeText(Categories.this, "Submission failed", Toast.LENGTH_LONG).show();
            }
        }

    });

【问题讨论】:

  • 记录用户 ID。 getUid() 可能不会返回任何内容
  • 从 firebase 分配的用户 ID 出现在我的 logcat 中,如下所示:'/traktrail.example.com D/FirebaseAuth: Notifying id token listeners about user (1JSfWVLNBQUDMDlBIT3mlqYJC6W2)。 /traktrail.example.com D/FirebaseAuth:通知有关用户的身份验证状态侦听器 (1JSfWVLNBQUDMDlBIT3mlqYJC6W2)。 '

标签: java firebase android-studio firebase-realtime-database


【解决方案1】:

我不是很有经验,但我相信我在尝试从 API 获取和更新信息时遇到了类似的问题。我认为您的问题来自多线程。当您调用 getUid() 函数时,它会创建一个新线程来获取所需的信息。此步骤需要一些时间来完成其任务并从数据库中获取 id。但是,您的 sendUserData() 函数完成其任务所需的时间更少。因此,您从 sendUserData() 函数进入代码的第三行,在该函数中您在线程完成之前使用您的 UserID 变量,留下一个空变量。

如果这是问题所在,您可以通过让应用程序等待线程完成来解决它,或者您可以在点击按钮之前获取用户 ID。我认为第一种方法更好,但是当我解决我的问题时,我找不到这样做的好方法。

对于第二种方法,您可以简单地在 onCreate() 方法的请求中创建您的 UserID 变量并在那里分配它的值。通过这样做,您将在创建活动时创建线程,从数据库中获取信息并关闭线程。当您尝试调用您的 sendUserData() 函数时,您已经为您准备好了 userId。

所以,不确定是不是这样,但试一试:)

【讨论】:

  • 非常感谢您的帮助!不幸的是我仍然无法让它工作:(但我真的很感谢你花时间帮助我:)
猜你喜欢
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
相关资源
最近更新 更多