Question regarding Expiry of reserved IDs of an auto-generated unique values configured with a text pattern containing CURRENT_DATE(MM-yyyy):

It says in this documentation the following:

:warning: Caution:
When using auto-generated unique values which contain dates as part of the pattern the expiryDate of those values will be linked to that date pattern which might result in unexpected behaviour if the pattern is not defined well.

Example: The value UniqueID has been configured with a pattern like CURRENT_DATE(MM)-SEQUENTIAL(###) and today is 31st of January, the application would download 100 values (from 01-001 to 01-101) to allow the application working offline and having enough values, but tomorrow, 1st of February, the application would not have any available values as all would have been marked as expired and so it would display such message.

I still couldn’t get my head around this process, anyhow, I configured the following text pattern as a unique id:

ORG_UNIT_CODE(…) + “-” + CURRENT_DATE(MM-yyyy) + “-” + SEQUENTIAL(######)

as you see it depends on the month, my question is when available reserved values are marked as expired does they are marked only in the android app? or they are marked in both the android app and on the server?, and does that affect the events that used some of these expired values as unique id and still not synced with the server until after the expiration, if I tried to sync these events after the expiration do they get synced? or does the server refuse it? in the past, I had a problem syncing some event and I remember it showed an error message that I don’t recall its content right now, but I wonder if that was due to the expiration of values that were used in these un-synced events.

I think you know my point, can anyone explain the concept a little more and clear the fog?


Hi Hamza,

I will try to explain and setting some examples but if it is not clear let me know as I think this is a tricky thing.

The Android App has been designed to work in offline mode, this means that will download everything it needs to work as such. For the Organisation Unit, Programs, etc this is not a big deal, just downloads what it is in the server and stores it in your phone.

This would be no problem if the user was only going to use the App in read-only mode, however, the application also allows you to enter data, and the way DHIS2 works is by using the UID which are these long strings that you might have seen i.e. qrur9Dvnyt5.

The problem can be easily solved: as DHIS2 allows you to generate in advance these strings, the Android apps gets a bunch of them (100) when it synchronizes and then keeps getting them every time you synchronize if those values are being exhausted. So sometimes will ask the server to get some and sometimes will not as you still have enough to work offline.

The auto-generated unique values work in a similar way of the process described above. If your pattern would be: ORG_UNIT_CODE(...)+SEQ(###) the first Android synchronizing would get SPA000 to SPA099. That is 100 values of those, and the server would mark those as used so the next Android synchronizing would get SPA100-SPA199 and so on.

Now, the tricky part comes if you start using Dates because Android cannot know if you will be using those values today, tomorrow or in one week. So basically it generates as of the moment you are requesting them. For example if your generation string is ORG_UNIT_CODE(…) + “-” + CURRENT_DATE(MM-yyyy) + “-” + SEQUENTIAL(######) it is going to generate, the following 100 codes: SPA092020-000000 to SPA092020-000099. Which seems to be perfect if you are using them today, or well, before the end of the month because on the 1st of October those values are considered expired which is true.

So, on the 1st of October your application will realize that the values are expired and will ask the server (in the next sync) to generate 100 new values in the form SPA102020-000000 to SPA102020-000099 and you will have one month to use them. Until the moment you perform that synchronization you will not be able to create new TEIs as there are no reserved values that can be used.

This doesn’t mean that what you have inserted as from today (moment you did the sync) until the end of the month are going to be wrong. They will be properly stored and synced with the server whenever you perform the sync, either today or in months, as when the reserved values where used they were correct and not expired.

Using a pattern like yours could be OK depending on your setup. If you know that your field workers could always retrieve new values as they have Internet connectivity should be no problem, however, if your field workers go offline for long periods of time without the possibility of syncing they could be left on the field without the possibility to create TEIs until they would sync.

By extension, using a pattern which uses CURRENT_DATE(dd-MM-yyyy) is bad option in most of the cases as the user will need to sync every day. The only use cases I could find this as valid is either a hospital with wireless connection or 3G always connected field workers.

Please note that you can always retrieve more values if you need, either by setting a higher number in the App settings or clicking on the REFILL option:


Thank you very much @jaime.bosque for the time you took explaining this detailed explanation.

1 Like

@jaime.bosque is it possible to find the last sequence given out . or forward the sequence to avoid a conflict (I mean from the web - I have a restored backup that is behind the reserved values)?

1 Like

Hey @samuel , I think you could easily get this via an API call to the server by generating a new value. For example I just modified the play instance 2.39 (will be valid only today 15-11-2022):

You will see there is a sequential that will give you the next one available, meaninig that the other ones have already been provided.

If there is another/better way to get this, probably @dhis2-backend / @tracker-backend can help

1 Like