为什么在插入了多个项目后,数组列表ratingItemList显示为空?

huangapple go评论93阅读模式
英文:

Why is the array list ratingItemList showing as empty after insertion of several items?

问题

package com.example.ratingapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.ArrayList;
import java.util.List;

public class YourRating extends AppCompatActivity {
private List<ratingItem> ratingItemList;
private FirebaseFirestore db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_your_rating);

        ratingItemList=new ArrayList<>();

        db = FirebaseFirestore.getInstance();
        db.collection("userRatings").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
            @Override
            public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                if(!queryDocumentSnapshots.isEmpty()){
                    Log.d("Check1","Ratings Exist");
                    List<DocumentSnapshot> documentSnapshots = queryDocumentSnapshots.getDocuments();
                    for(DocumentSnapshot doc : documentSnapshots) {
                        String rating = doc.getString("Rating");
                        //Log.d("Rating",rating);
                        com.google.firebase.Timestamp date = doc.getTimestamp("Date");
                        //Log.d("Date",date.toString());
                        ratingItem newRatingItem = new ratingItem(rating, date);
                        Log.d("Rating", newRatingItem.getRating());
                        Log.d("Date", newRatingItem.getTimestamp().toString());

                        ratingItemList.add(newRatingItem);
                        Log.d("Size ",String.valueOf(ratingItemList.size()));
                    }
                }
                else{
                    Toast.makeText(YourRating.this,"No ratings available!",Toast.LENGTH_LONG).show();
                }
            }
        });

        if(ratingItemList.isEmpty()){
            Log.d("Empty","Empty List");
        }
        for(ratingItem r: ratingItemList){
            Log.d("Rating1",r.getRating());
            Log.d("Date1",r.getTimestamp().toString());
        }
    }

}
英文:

While its in the Document Snapshot loop its adding the ratings to the ratingItemList. I know this for sure because I'm also printing the size of the list in the Log and it's increasing.
But after it comes out of that loop just to be sure I check whether it is empty or not and it prints Empty List in the log.
Can you guys help me out locating the error?

package com.example.ratingapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.List;
public class YourRating extends AppCompatActivity {
private List&lt;ratingItem&gt; ratingItemList;
private FirebaseFirestore db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your_rating);
ratingItemList=new ArrayList&lt;&gt;();
db = FirebaseFirestore.getInstance();
db.collection(&quot;userRatings&quot;).get().addOnSuccessListener(new OnSuccessListener&lt;QuerySnapshot&gt;() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if(!queryDocumentSnapshots.isEmpty()){
Log.d(&quot;Check1&quot;,&quot;Ratings Exist&quot;);
List&lt;DocumentSnapshot&gt; documentSnapshots = queryDocumentSnapshots.getDocuments();
for(DocumentSnapshot doc : documentSnapshots) {
String rating = doc.getString(&quot;Rating&quot;);
//Log.d(&quot;Rating&quot;,rating);
com.google.firebase.Timestamp date = doc.getTimestamp(&quot;Date&quot;);
//Log.d(&quot;Date&quot;,date.toString());
ratingItem newRatingItem = new ratingItem(rating, date);
Log.d(&quot;Rating&quot;, newRatingItem.getRating());
Log.d(&quot;Date&quot;, newRatingItem.getTimestamp().toString());
ratingItemList.add(newRatingItem);
Log.d(&quot;Size &quot;,String.valueOf(ratingItemList.size()));
}
}
else{
Toast.makeText(YourRating.this,&quot;No ratings available!&quot;,Toast.LENGTH_LONG).show();
}
}
});
if(ratingItemList.isEmpty()){
Log.d(&quot;Empty&quot;,&quot;Empty List&quot;);
}
for(ratingItem r: ratingItemList){
Log.d(&quot;Rating1&quot;,r.getRating());
Log.d(&quot;Date1&quot;,r.getTimestamp().toString());
}
}
}

答案1

得分: 1

如果您在第一行调用后台线程结果并在紧接着的下一行打印它,您的回调方法不能保证在紧接着的下一行之前运行。它将开始执行第一行的线程,并在等待响应的情况下运行下一行。因此,您会得到一个空结果。

在回调的 onSuccess() 方法中,也要在 for 循环之后检查列表大小:

public class YourRating extends AppCompatActivity {
    private List<ratingItem> ratingItemList;
    private FirebaseFirestore db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_your_rating);

        ratingItemList = new ArrayList<>();

        db = FirebaseFirestore.getInstance();
        db.collection("userRatings").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
            @Override
            public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                if (!queryDocumentSnapshots.isEmpty()) {
                    Log.d("Check1", "Ratings Exist");
                    List<DocumentSnapshot> documentSnapshots = queryDocumentSnapshots.getDocuments();
                    for (DocumentSnapshot doc : documentSnapshots) {
                        String rating = doc.getString("Rating");
                        //Log.d("Rating",rating);
                        com.google.firebase.Timestamp date = doc.getTimestamp("Date");
                        //Log.d("Date",date.toString());
                        ratingItem newRatingItem = new ratingItem(rating, date);
                        Log.d("Rating", newRatingItem.getRating());
                        Log.d("Date", newRatingItem.getTimestamp().toString());

                        ratingItemList.add(newRatingItem);
                        Log.d("Size ", String.valueOf(ratingItemList.size()));
                    }
                    if (ratingItemList.isEmpty()) {
                        Log.d("Empty", "Empty List");
                    }
                    for (ratingItem r : ratingItemList) {
                        Log.d("Rating1", r.getRating());
                        Log.d("Date1", r.getTimestamp().toString());
                    }
                } else {
                    Toast.makeText(YourRating.this, "No ratings available!", Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}
英文:

if you call for background thread result in first line and print it on very next line, your callback method does not give guarantee to run before the very next line. It will start to execute thread of first line and without waiting for response run the next line. So you are getting it empty.

Check list size also in callback onSuccess() method, after for loop:

public class YourRating extends AppCompatActivity {
private List&lt;ratingItem&gt; ratingItemList;
private FirebaseFirestore db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your_rating);
ratingItemList = new ArrayList&lt;&gt;();
db = FirebaseFirestore.getInstance();
db.collection(&quot;userRatings&quot;).get().addOnSuccessListener(new OnSuccessListener&lt;QuerySnapshot&gt;() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (!queryDocumentSnapshots.isEmpty()) {
Log.d(&quot;Check1&quot;, &quot;Ratings Exist&quot;);
List&lt;DocumentSnapshot&gt; documentSnapshots = queryDocumentSnapshots.getDocuments();
for (DocumentSnapshot doc : documentSnapshots) {
String rating = doc.getString(&quot;Rating&quot;);
//Log.d(&quot;Rating&quot;,rating);
com.google.firebase.Timestamp date = doc.getTimestamp(&quot;Date&quot;);
//Log.d(&quot;Date&quot;,date.toString());
ratingItem newRatingItem = new ratingItem(rating, date);
Log.d(&quot;Rating&quot;, newRatingItem.getRating());
Log.d(&quot;Date&quot;, newRatingItem.getTimestamp().toString());
ratingItemList.add(newRatingItem);
Log.d(&quot;Size &quot;, String.valueOf(ratingItemList.size()));
}
if (ratingItemList.isEmpty()) {
Log.d(&quot;Empty&quot;, &quot;Empty List&quot;);
}
for (ratingItem r : ratingItemList) {
Log.d(&quot;Rating1&quot;, r.getRating());
Log.d(&quot;Date1&quot;, r.getTimestamp().toString());
}
} else {
Toast.makeText(YourRating.this, &quot;No ratings available!&quot;, Toast.LENGTH_LONG).show();
}
}
});
}
}

答案2

得分: 0

你的成功监听器在后台线程上运行,它是一个承诺,将在从 Firebase 获取数据时运行。另一方面,检查数组列表是否为空的代码片段在 UI 线程上运行。它不会等待数据被获取。

英文:

you success listener runs on the background thread and it is a promise that will be run when the data will be obtained from the firebase.
on the other hand the piece of code where you check the array list is empty or not runs on the ui thread. It does not wait for the data to be fetched.

huangapple
  • 本文由 发表于 2020年4月7日 20:53:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/61080499.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定