I decided to use intent service for a task involving looping big number of results, calculating a summary result and inserting it back in firestore. This is how i am calling my intent service from activity.
onDataSnapShotListenerForPointsAndRating = db.collection("PointsAndRating")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
@Nullable FirebaseFirestoreException e) {
Intent serviceIntent = new Intent(PlayWithMrMathActivitySinglePlayer.this,
MyIntentService.class);
serviceIntent.putExtra("SENDER", "Mr. Math");
serviceIntent.putExtra("emailAddress", emailAddress);
serviceIntent.putExtra("OwnID", OwnID);
Log.d(TAG, "Hello MyIntentService: I am Mr Math and i am starting service");
**startService(serviceIntent);**
}
});
This is how I am doing that big loop work:
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent: inside onHandleIntent ");
String sender = intent.getStringExtra("SENDER");
emailAddress = intent.getStringExtra("emailAddress");
OwnID = intent.getStringExtra("OwnID");
Log.d(TAG, "onHandleIntent: inside onHandleIntent sender = " + sender);
Log.d(TAG, "onHandleIntent: inside onHandleIntent emailAddress = " + emailAddress);
Log.d(TAG, "onHandleIntent: inside onHandleIntent OwnID = " + OwnID);
Log.d(TAG, "onDataSnapShotListenerForPointsAndRating: ");
Log.d(TAG, "onHandleIntent: currentThread = " + Thread.currentThread().getId());
db.collection("PointsAndRating")
.orderBy("gmq", Query.Direction.DESCENDING)
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot>task) {
Long myWorldRank = new Long(0);
Log.d(TAG, "onComplete: onDataSnapShotListenerForPointsAndRating = " + task.getResult().size());
if (task.isSuccessful()) {
Log.d(TAG, "onHandleIntent InonComplete : If currentThread = " + Thread.currentThread().getId());
for (QueryDocumentSnapshot document: task.getResult()) {
Log.d(TAG, document.getId() + "= onDataSnapShotListenerForPointsAndRating =@@ => " + document.getData());
myWorldRank = myWorldRank + 1;
if (document.getId().equals(emailAddress)) {
break;
}
***Log.d(TAG, "onHandleIntent InonComplete : For Loop currentThread = " + Thread.currentThread().getId());***
} // end of for loop
Log.d(TAG, "onDataSnapShotListenerForPointsAndRating: Rank = " + myWorldRank);
}
final Map<String, Object> myWorldRankUpdateNugget = new HashMap<>();
myWorldRankUpdateNugget.put("myWorldRank", myWorldRank);
db.collection("PointsAndRating")
.whereEqualTo("userID", OwnID)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document: task.getResult()) {
db.collection("PointsAndRating")
.document(document.getId())
.set(myWorldRankUpdateNugget, SetOptions.merge())
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Log.d(TAG, "onDataSnapShotListenerForPointsAndRating: WORLD RANK UPDATED ");
}
});
} // end of for loop
}
Log.d(TAG, "onHandleIntent: EXIT currentThread = " + Thread.currentThread().getId());
}
});
}
});
} // end of onhandle
and i see this in logs.
06-28 17:48:34.068 11076-11154/com.udiversity.myapplication D/MyIntentService: onHandleIntent: currentThread = 3867
06-28 17:49:36.118 11076-11076/com.udiversity.myapplication D/PlayWithMrMathActivitySinglePlayer: onCreate: currentThread = 1
06-28 17:49:36.118 11076-11076/com.udiversity.myapplication D/PlayWithMrMathActivitySinglePlayer: OnSubmitPOC: currentThread Back Home OnCreate
06-28 17:49:36.118 11076-11106/com.udiversity.myapplication D/PlayWithMrMathActivitySinglePlayer: doInBackground: currentThread = 3837
06-28 17:49:36.148 11076-11076/com.udiversity.myapplication D/PlayWithMrMathActivitySinglePlayer: onProgressUpdate currentThread = 1
06-28 17:49:36.158 11076-11076/com.udiversity.myapplication D/PlayWithMrMathActivitySinglePlayer: onProgressUpdate EXIT 1 currentThread = 1
06-28 17:49:48.328 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : If currentThread = 1
06-28 17:49:48.328 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.328 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.328 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.328 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
06-28 17:49:48.338 11076-11076/com.udiversity.myapplication D/MyIntentService: onHandleIntent InonComplete : For Loop currentThread = 1
Why this loop inside onHandleIntent->db.Collection("").get().onComplete() is running on main thread ?
public class MyIntentService extends IntentService {
private static final String TAG = "MyIntentService";
FirebaseFirestore db = FirebaseFirestore.getInstance();
db is my local class database instance.