[cloud functions] Add check that active_configurations isn't empty

Because the active_configurations document is loaded long
before modifying it, reload after the modification to see
if it is empty. Race conditions have caused the last two
configurations to be removed simultaneously, so neither
update thought it was removing the last configuration.

Change-Id: I28251df80c0d2dda430c89e6519f19412a5ee98e
TBR: athom@google.com
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/134660
Reviewed-by: William Hesse <whesse@google.com>
diff --git a/functions/node/firestore_impl.dart b/functions/node/firestore_impl.dart
index d701705..eb179cd 100644
--- a/functions/node/firestore_impl.dart
+++ b/functions/node/firestore_impl.dart
@@ -240,18 +240,19 @@
 
   Future<void> updateActiveResult(
       Map<String, dynamic> activeResult, String configuration) async {
-    final updateData = UpdateData();
+    final document = firestore.document('results/${activeResult['id']}');
     if (activeResult['active_configurations'].length > 1) {
-      updateData.setFieldValue('active_configurations',
-          Firestore.fieldValues.arrayRemove([configuration]));
-    } else {
-      updateData.setFieldValue(
-          'active_configurations', Firestore.fieldValues.delete());
-      updateData.setFieldValue('active', Firestore.fieldValues.delete());
+      final removeConfiguration = UpdateData()
+        ..setFieldValue('active_configurations',
+            Firestore.fieldValues.arrayRemove([configuration]));
+      await document.updateData(removeConfiguration);
+      activeResult = (await document.get()).data.toMap();
+      if (activeResult['active_configurations'].isNotEmpty) return;
     }
-    return firestore
-        .document('results/${activeResult['id']}')
-        .updateData(updateData);
+    final deleteActiveFields = UpdateData()
+      ..setFieldValue('active_configurations', Firestore.fieldValues.delete())
+      ..setFieldValue('active', Firestore.fieldValues.delete());
+    return document.updateData(deleteActiveFields);
   }
 
   Future<Map<String, dynamic>> findActiveResult(