I was previously assuming I could create a user id, which I called "oa_uid" in the SDK. But after my own testing a few times, I realized it makes much more sense to do that on the server, after looking up the various things like IP/Device IDs etc. Not sure why I thought creating the ID on startup in the app was OK, but it definitely doesn't work very well since it can't handle any reattributions.
So I think that flow might go:
First time start, send "app_open" and wait for server to reply with an "oa_uid"
Store "oa_uid" on device
Use "oa_uid" in each subsequent event