Skip to content

Server tasks

Server tasks are actions requested by the client app and fulfilled by the backend. Clients write to

/serverTasks/<id>/request
and observe
/serverTasks/<id>/response

after which they delete the whole task from db. Task contains a response code which is ok, error or something else specific to a task.

Server tasks should have a unified UI - screen with a determinate progressbar based on timeout and they should run even if the user leaves the app (permanent notification on Android).

  • Server tasks should not be launched offline
  • If the device is offline, an error should be shown
  • If the device is online but Firebase is not connected, we will wait for connection until timeout

Timeouts:

  • connect to Firebase = 30s
  • currencyChange = 30s
  • all other = 20s

Here's a list of all tasks:

    // force recalculate group debts
    "calculateGroupsDebts": {
      "task_id_1": {
        "serverTimestamp": 21312321321,
        "request": {
          "groupId": "group_id_1"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // import members & their balances from supported supported service (e.g. Splitwise)
    "importMemberBalances": {
      "task_id_1": {
        "serverTimestamp": 21312321321,
        "request": {
          "source": "splitwise",
          "data": "serialized_file_content"
        },
        "response": {
          "code": "ok",
          "currency": "USD",
          "memberBalances": [{
            "name": "John",
            "balance": "25.00"
          },{
            "name": "Eva",
            "balance": "-25.00"
          }]
        }
      }
    },
    // user picked a reward, activate it
    "activateUserReward": {
      "task_id_1": {
        "serverTimestamp": 21312321321,
        "request": {
          "rewardId": "reward_id_1",
          "type": "featureReward",
          "feature": "colors"
        },
        "response": {
          "code": "ok",
          "subscriptionId": "subscription_id_1"
        }
      }
    },
    // verify subscription receipt and seed /subscriptions/<uid>/
    "verifySubscription": {
      "task_id_1": {
        "serverTimestamp": 21312321321,
        "request": {
          "store": "googlePlay",
          "receipt": "dsajldjsakljlkdsa",
          "type" : "monthly"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // change group currency, this requires updating all transactions in the group
    "currencyChange" : {
      "task_id_3": {
        "serverTimestamp": 21312321321,
        "request": {
          "groupId": "group_id_1",
          "targetCurrency": "CZK"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // delete group, backend will actually just archive it and mark it for deletion later
    "deleteGroup" : {
      "task_id_4": {
        "serverTimestamp": 21312321322,
        "request": {
          "groupId": "group_id_2"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // delete archived group
    "deleteArchivedGroup" : {
      "task_id_4": {
        "serverTimestamp": 21312321322,
        "request": {
          "groupId": "group_id_2"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // delete all transactions in group
    "deleteTransactions" : {
      "task_id_5": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_3"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // archive group to Storage, users will see it in their Groups list
    "archiveGroup" : {
      "task_id_6": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_3"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // temporarily restore archived group in preview
    "previewGroup" : {
      "task_id_7": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_3"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // fully restore archived group
    "restoreGroup" : {
      "task_id_8": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_3"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // active empty Group Premium (one which doesn't have groupId set) for a specied group
    "activateEmptyGroupPremium" : {
      "task_id_9": {
        "serverTimestamp": 21312321323,
        "request": {
          "subscriptionId": "subscription_id_1",
          "groupId": "group_id_5"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // verify Group Premium purchase and set group as Premium
    "verifyGroupPremium" : {
      "task_id_10": {
        "serverTimestamp": 21312321323,
        "request": {
          "store": "googlePlay",
          "receipt": "dsajldjsakljlkdsa",
          "groupId": "group_id_5",
          "extendSubscriptionId": "subscription_id_1" // optional, for renewing Group Premium
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // update exchange rates in bulk for all transactions
    "updateExchangeRates" : {
      "task_id_11": {
        "serverTimestamp": 21312321323,
        "request": {
          "exchangeRatesToGroupCurrency": {
            "EUR": "25.0001",
            "USD": "automatic"
          },
          "groupId": "group_id_5"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // clone group into a new one, optionally archiving the old group
    "cloneGroup" : {
      "task_id_12": {
        "serverTimestamp": 21312321323,
        "request": {
          "cloneMembers": true,
          "cloneDebts": true,
          "clonePermissions": true,
          "cloneRecurringTransactions": true,
          "archiveOldGroup": true,
          "debtTransactionPurpose": "Converted debt from %s",
          "oldGroupId": "group_id_5",
          "oldGroupName": "old_group_name",
          "newGroupName": "new_group_name"
        },
        "response": {
          "code": "ok",
          "newGroupId": "group_id_11"
        }
      }
    },
    // delete all user data, can fail if user is owner of a group
    "deleteUser": {
      "task_id_13": {
        "serverTimestamp": 21312321323,
        "request": {
          "uid": "user_id_123",
          "force": true // if user is owner of some groups they are either deleted or transferred to someone else
        },
        "response": {
          "code": "error",
          "ownedGroupIds": [ "group_id_1" ], // groups user ownes they need to transfer to someone else
          "subscriptionId": "sub_id_1" // active subscription which couldn't be cancelled automatically
        }
      }
    },
    // remind all users in a group about their debts
    "remindAllDebts" : {
      "task_id_14": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_5"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // remind the debtor about a specific debt
    "remindDebt" : {
      "task_id_10": {
        "serverTimestamp": 21312321323,
        "request": {
          "groupId": "group_id_5",
          "fromMemberId": "member_id_1",
          "toMemberId": "member_id_2",
          "amount": "500"
        },
        "response": {
          "code": "ok"
        }
      }
    },
    // cancel subscription
    "cancelSubscription": { // Only for Stripe & Google Play
      "request": {
        "subscriptionId": "sub_id_1"
      },
      "response": {
        "code": "ok"
      }
    }