Проблема здесь заключалась в том, что API был разработан странным образом (и, к сожалению, имеет очень плохую документацию).Я не мог понять, почему я получал дубликаты, и подумал, что я неправильно использовал flatMapIterable
.
То, что на самом деле создает вызов deviceCredentialService.getCredentials()
, - это наблюдаемое, которое испускает DataEvent
объекты, которые являются простыми обертками надсписок результатов и с флагом того, откуда пришли результаты.
Разработчик API хотел разрешить пользователю использовать локально кэшированные данные для немедленного заполнения пользовательского интерфейса при выполнении более длинного запроса к API REST.Свойство DataEvent.from
- это перечисление, которое помечает источник либо из локального кэша устройства, либо из удаленного вызова API.
Я решил это, просто проигнорировав результаты, поступающие из локального кэша, и выполнив только команду emit.Результаты из API:
Observable<DeviceCredential> getCredentials() {
return deviceCredentialService()
.getCredentials()
// Only get creds from network
.filter(e -> e.getFrom() == SyncedDataSourceObservableFactory.From.SOURCE)
.flatMapIterable(e -> e.getData());
}
Single<Organization> getOrgFromCreds(String orgid) {
return getCredentials()
// A device is logically constrained to only have a single cred per org
.map(DeviceCredential::getOrganization)
.filter(org -> org.getId().equals(orgid))
.singleOrError();
}
В этом случае планируется использовать запоминание для кэширования сущностей таким образом, чтобы дать реализующему приложению доступ к аннулированию кэша.Поскольку предоставленный интерфейс не позволяет подавлять вызов API, невозможно работать только с кешем, если приложение чувствует, что оно свежо.