FirebaseUI-iOS FUIIndexArray Usage

298 views Asked by At

Since currently FirebaseUI's FUICollectionDataSource handles all changes to the UI, I'm using FUIArray and observing the changes to the datasource as well as manually updating my collectionView. However on second glance I believe I should have implemented FUIIndexArray, because of its ordering behavior. However, I am not sure as to it's two init queries.

From the docs:

  • @param index A Firebase database query whose childrens' keys are all children of the data query.
  • @param data A Firebase database reference whose children will be fetched and used to populate the array's contents according to the index query.

For the data param, I am using the same query that I used with the FUIArray (which worked). For the index param, I wasn't sure what to use so I used the same query to test and it seems to be half working. In both queries, I am sorting by priority. If I check the length of the the FUIIndexArray, I get the correct count but when I check its .items the array is empty.

Is FUIIndexArray supposed to work similarly to FUIArray, except that it returns an index as well? What should the index query look like?

1

There are 1 answers

2
Morgan Chen On BEST ANSWER

Looks like there's some confusion around what an FUIIndexArray is actually supposed to do. FUIIndexArray uses the keys of the children of the index query to load children from the data query, which means each element load becomes asynchronous and .items won't return anything if none of those loads have completed (although maybe it should return an array full of NSNull here).

FUIIIndexArray was designed to make loading very granular sections of large data sets easier by taking a query to specify exactly which elements should be loaded. Say your database looks like this:

// An index to track Ada's memberships
{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      // Index Ada's groups in her profile
      "groups": {
         // the value here doesn't matter, just that the key exists
         "techpioneers": true,
         "womentechmakers": true
      }
    },
    ...
  },
  "groups": {
    "techpioneers": {
      "name": "Historical Tech Pioneers",
      "members": {
        "alovelace": true,
        "ghopper": true,
        "eclarke": true
      }
    },
    ...
  }
}

If both users and groups are very large data sets, you'll want to be able to download selectively only the groups that a specific user belongs to. FUIIndexArray solves exactly this use case (and nothing else).

let adasGroups = database.reference(withPath: "users/alovelace/groups")
let allGroups  = database.reference(withPath: "groups")

// array will load only alovelace's groups
let array = FUIIndexArray(index: adasGroups, data: allGroups, delegate:self)

Since each element must be loaded individually, FUIIndexArrayDelegate provides a callback for handling each load individually and implementing this callback to handle both successful loads and errors correctly can add fractal complexity to your codebase. You should avoid using FUIIndexArray when you can and stick to the much simpler FUIArray, especially if your query limiting needs can be met without an index.