【问题标题】:Firebase Cloud Firestore - getting a document to custom object and passing it to another activityFirebase Cloud Firestore - 将文档获取到自定义对象并将其传递给另一个活动
【发布时间】:2018-03-20 17:04:32
【问题描述】:

我正在尝试将存储在 Firebase Cloud Firestore 中的文档获取到我的自定义对象(动物)。我需要将此对象传递给另一个活动。我使用了intent.putextra("class name", obj) 函数,但我无法访问我为获取文档而创建的对象。这是我的代码:

public void start(View view){

String id;
EditText animalIdEditText = findViewById(R.id.animalIDsearch);
String animalId = animalIdEditText.getText().toString();
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference docRef = db.collection("Animals").document(animalId);
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        Animal animal = documentSnapshot.toObject(Animal.class); // this is where I create animal object. It doesn't let me declare it above either.
    }
});

    Intent intent = new Intent(this, searchActivity.class);
    intent.putExtra("Animal",animal); // error in this line : animal  can't be resolved
    startActivity(intent);
}

【问题讨论】:

  • Firebase API 是异步的,在访问数据时会立即返回。您需要为此设计,仅在回调中使用获取的数据。 medium.com/google-developers/…
  • @asls2 你成功了吗?
  • 是的,谢谢你的帮助。
  • @asls2 我知道你是个初学者。认为像您这样的未来访问者会访问这篇文章,他们会认为将对象传递给方法将解决 onSuccess() 方法的异步行为,但它不会......
  • @asls2 感谢您做正确的事。

标签: java android firebase android-intent google-cloud-firestore


【解决方案1】:

要解决这个问题,你需要等待数据,为了实现这个,你需要创建一个这样的自定义回调:

public interface MyCallback {
    void onCallback(Animal animal);
}

然后你需要创建看起来像这样的方法:

public void readData(MyCallback myCallback) {
    String id;
    EditText animalIdEditText = findViewById(R.id.animalIDsearch);
    String animalId = animalIdEditText.getText().toString();
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    DocumentReference docRef = db.collection("Animals").document(animalId);
    docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(DocumentSnapshot documentSnapshot) {
            Animal animal = documentSnapshot.toObject(Animal.class);
            myCallback.onCallback(animal);
        }
    });
}

最后,只需调用readData() 方法并将MyCallback 接口的实例作为参数传递到您在活动中需要它的任何位置,如下所示:

readData(new MyCallback() {
    @Override
    public void onCallback(Animal animal) {
        Intent intent = new Intent(this, searchActivity.class);
        intent.putExtra("Animal", animal);
        startActivity(intent);
    }
});

有关更多信息,您可以查看我在 this post 以及此 video 的回答。

【讨论】:

  • 这也有效。可悲的是,我无法将其中两个答案标记为有帮助。谢谢你的详细解释。赞赏!
  • 您能解释一下这里需要第二次回调吗?
  • @LeviAlbuquerque 不是第二个回调,它是第一个也是单个回调,需要使用它才能在该方法之外使用该对象。请参阅上面的我的 cmets。
  • 我不明白回调的必要性,这就是我使用“第二个”回调的原因,因为第一个回调将是 firebase 的 onSuccess。如果从当前类调用方法会容易得多,我不明白为什么要增加额外的复杂层
  • 我看到您仍然不了解回调的需要,但这是异步调用的工作方式。 “从当前类调用方法会容易得多”,你是对的。但如果需要在外面呢?如果外部需要,则需要回调。在该示例中,他们没有在外部使用这些值,因为不需要。为什么要使用回调?在 OP 的代码中,他试图在外部使用 animal 对象。
猜你喜欢
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多