title: Running Firebase callback on another thread is blocking UI
body: <p>I know this question might seem duplicated, I've read like ten other threads about this same thing, but I cannot find the problem</p>
  
  <p>I have this method in my activity:</p>
  
  <pre><code>public void saveResponse(final Response studentResponse, final Content content)
      fb.getReference("...").addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
          public void onDataChange(final DataSnapshot dataSnapshot) {
  
             new Thread(new Runnable() {
                 @Override
                 public void run() {
                      Map&lt;String, Object&gt; responseMap = new HashMap&lt;&gt;();
                      responseMap.put("end_date", studentResponse.end_date);
                      responseMap.put("start_date", studentResponse.start_date);
                      responseMap.put("time", studentResponse.time);
                      responseMap.put("points", studentResponse.points);
                      responseMap.put("max_points", studentResponse.max_points);
                      responseMap.put("selected_options", studentResponse.selected_options);
                      if (!TextUtils.isEmpty(studentResponse.free_text))
                          responseMap.put("free_text", studentResponse.free_text);
  
                      DataSnapshot contentRef = dataSnapshot.child("/sections/" + currentSection + "/sections/" + currentSubsection + "/contents/" + content.id);
                      final int oldPoints = contentRef.hasChild("points") ? contentRef.child("points").getValue(int.class) : 0;
                      contentRef.getRef().setValue(responseMap);
                      contentRef.getRef().setPriority(ServerValue.TIMESTAMP);
  
                      DataSnapshot subSectionRef = dataSnapshot.child("/sections/" + currentSection + "/sections/" + currentSubsection);
                      long subSectionPoints = (subSectionRef.hasChild("points") ? subSectionRef.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
                      subSectionRef.child("points").getRef().setValue(subSectionPoints);
  
                      int indexOf = currentContents.indexOf(content) + 1;
                      if(indexOf &gt; 0 &amp;&amp; indexOf &lt; currentContents.size()) {
                          CourseContent content = currentContents.get(indexOf);
                          subSectionRef.child("currentPosition").getRef().setValue(content.order);
                      }
  
                      DataSnapshot sectionRef = dataSnapshot.child("/sections/" + currentSection);
                      long sectionPoints = (sectionRef.hasChild("points") ? sectionRef.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
                      sectionRef.child("points").getRef().setValue(sectionPoints);
  
                      long coursePoints = (dataSnapshot.hasChild("points") ? dataSnapshot.child("points").getValue(long.class) : 0) + studentResponse.points - oldPoints;
                      dataSnapshot.child("points").getRef().setValue(coursePoints);
                      dataSnapshot.getRef().setPriority(MAX_SAFE_INTEGER - coursePoints);
  
                      int completed = 0;
                      for (DataSnapshot sect : dataSnapshot.child("sections").getChildren()) {
                          for (DataSnapshot subSect : sect.child("sections").getChildren()) {
                              int currPos = subSect.hasChild("currentPosition") ? subSect.child("currentPosition").getValue(int.class) : 0;
                              completed += currPos;
                          }
                      }
  
                      double progress = totalContents &gt; 0 ? (double) completed / (double) totalContents : 0;
                      dataSnapshot.child("progress").getRef().setValue(progress);
                 }
             }.start();
          }
          ...
      });
  }
  </code></pre>
  
  <p>in a click handler I call this method, and then I change the fragment (with custom animations).</p>
  
  <p>The thing is, the fragment transition is not smooth, it freezes a little, if I comment everything inside the runnable then it runs smooth. I've tried also with an AsyncTask and the same happens.</p>
  
  <p>Inside the runnable, I'm just querying the dataSnapshot and its children, and setting some values (<code>dataSnapshot.child("item").getRef().setValue(x)</code>)</p>
  
  <p>Another strange thing is that if I put a breakpoint inside run(), it also works smooth.</p>