英文:
Pass data from firebase to object class
问题
问题是当我设置文本视图时,总是会出现空指针异常,因此我无法将文本设置为我的视图。
我认为对象没有从getData方法中填充字段。如何修复这个问题?
我正在按照以下步骤进行操作:https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection 和 https://stackoverflow.com/questions/52172309/parcelable-object-passing-from-android-activity-to-fragment。
这是来自Android Studio控制台的错误输出:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my.plkbi, PID: 24337
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.my.plkbi.Layanan.getSyarat()' on a null object reference
at com.my.plkbi.SubMainFragment.onCreateView(SubMainFragment.java:78)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
编辑:添加构造函数以从其他对象添加对象,我遵循了https://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java
这是有关字段数据库和Parcelable的对象:
public class Layanan implements Parcelable {
// ...(省略其他代码)
//Constructor to add value from another object
public Layanan(Layanan another) {
this.Nama = another.Nama;
this.Syarat = another.Syarat;
this.Langkah = another.Langkah;
this.Lampiran = another.Lampiran;
}
// ...(省略其他代码)
}
这是我从Firebase获取数据的方式,它在活动中:
public class MainActivity extends AppCompatActivity {
// ...(省略其他代码)
Layanan UP;
Layanan GU;
Layanan LS;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
// ...(省略其他代码)
getData("UP");
Log.d(TAG, "This is the value name of " + UP.getNama()); //Output: This is the value name of null
extras.putParcelable(UPParcelable, UP);
if (UP.getSyarat() != null) Log.d(TAG, "Value Added");
if (UP.getSyarat() == null) Log.d(TAG, "Value not Added"); //Output: Value not Added
homeFragment.setArguments(extras);
getSupportFragmentManager().beginTransaction().add(R.id.main_activity, homeFragment).commit();
}
// ...(省略其他代码)
}
// ...(省略其他代码)
public void getData(final String p) {
mFirebase.collection("panduan_layanan")
.whereEqualTo("nama", p)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
// ...(省略其他代码)
});
}
// ...(省略其他代码)
}
非常感谢。
英文:
The issue I have is there're always Null Pointer Exception when I settext textview, so I cannot setText to my view.
I think the object didn't fill the field from getData method. How to fix this?
I am following this step https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection and this https://stackoverflow.com/questions/52172309/parcelable-object-passing-from-android-activity-to-fragment.
This is the error output from android studio console
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my.plkbi, PID: 24337
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.my.plkbi.Layanan.getSyarat()' on a null object reference
at com.my.plkbi.SubMainFragment.onCreateView(SubMainFragment.java:78)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
EDIT: Add constructor to add object from other object, I follow this https://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java
This is the object about the field database and Parcelable
public class Layanan implements Parcelable {
private String Nama;
private String Syarat;
private String Langkah;
private String Lampiran;
public Layanan(){
//this("connect to internet", "connect to internet", "connect to internet", "connect to internet");
}
//Constructor to add value from another object
public Layanan(Layanan another) {
this.nama = another.nama;
this.syarat = another.syarat;
this.langkah = another.langkah;
this.lampiran = another.lampiran;
this.deskripsi = another.deskripsi;
}
protected Layanan(Parcel in) {
Nama = in.readString();
Syarat = in.readString();
Langkah = in.readString();
Lampiran = in.readString();
}
public static final Creator<Layanan> CREATOR = new Creator<Layanan>() {
@Override
public Layanan createFromParcel(Parcel in) {
return new Layanan(in);
}
@Override
public Layanan[] newArray(int size) {
return new Layanan[size];
}
};
public static Layanan newInstance() {
Bundle args = new Bundle();
Layanan fragment = new Layanan();
fragment.setArguments(args);
return fragment;
}
private void setArguments(Bundle args) {
}
public String getNama() {
return Nama;
}
public String getSyarat() {
return Syarat;
}
public void setSyarat(String syarat) {
Syarat = syarat;
}
public String getLangkah() {
return Langkah;
}
public void setNama(String nama) {
Nama = nama;
}
public void setLangkah(String langkah) {
Langkah = langkah;
}
public String getLampiran() {
return Lampiran;
}
public void setLampiran(String lampiran) {
Lampiran = lampiran;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Nama);
dest.writeString(Syarat);
dest.writeString(Langkah);
dest.writeString(Lampiran);
}
}
This is how i get data from Firebase, it's inside in activity
Layanan UP;
Layanan GU;
Layanan LS;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
//initMF();
MainFragment homeFragment = MainFragment.newInstance();
Bundle extras = new Bundle();
getData("UP");
Log.d(TAG, "This is the value name of " + UP.getNama()); //Output: This is the value name of null
extras.putParcelable(UPParcelable, UP);
if (UP.getSyarat()!=null) Log.d(TAG, "Value Added");
if (UP.getSyarat()==null) Log.d(TAG, "Value not Added"); //Output: Value not Added
homeFragment.setArguments(extras);
getSupportFragmentManager().beginTransaction().add(R.id.main_activity, homeFragment).commit();
}
...
...
public void getData(final String p){
mFirebase.collection("panduan_layanan")
.whereEqualTo("nama", p)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException e) {
if (e != null){
Log.w(TAG, "onEvent:error", e);
return;
}
Layanan newLayanan = new Layanan();
for (QueryDocumentSnapshot doc : value) {
if (doc.get("nama") != null && doc.get("syarat") != null && doc.get("langkah") != null && doc.get("lampiran")!= null){
newLayanan.setNama(doc.getString("nama"));
newLayanan.setLampiran(doc.getString("lampiran"));
newLayanan.setLangkah(doc.getString("langkah"));
newLayanan.setSyarat(doc.getString("syarat"));
Log.d(TAG, "Update data: Success" + p);
Log.d(TAG, "This is the " + p + " syarat" + newLayanan.getSyarat());
if (newLayanan.getSyarat() != null) Log.d(TAG, "new layanan is" + newLayanan.getNama()); //new layanan isUP, it is work too
}
}
if (p.equals("UP")) UP = new Layanan(newLayanan);
Log.d(TAG, "the" + UP.getNama()); //Output theUP so it is work in here
if (p.equals("GU")) GU = new Layanan(newLayanan);
if (p.equals("LS")) LS = new Layanan(newLayanan);
}
});
}
...
Thank you so much
答案1
得分: 0
因为 Firebase 会异步执行该代码块,所以你不能这样做。因此,该字段不会立即获得值,就像 Frank 的评论所说的那样。
英文:
You can't do that because firebase execute that block asynchronously. So the field doesn't get value immediately just like Frank's comment said
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论