UUID in React Native with Expo

Quddus George

Building a Mobile Application

What is a UUID?

What is a UUID?

UUID stands for Universally Unique Identifier. Usually it will be a string that is programmatically generated and thoroughly random. There are standards and measurements as to how random and how unique a string will be.

At what point will a given ID repeat itself? Hopefully never in your app. 😆

In General

You will need UUIDs for dynamically generated content. If you reference the title of an object, say a grocery list item, in order to pull the specific data things fall apart quickly when the user lists oranges 🍊 twice.

For the most simple of usecases an index may be unique. There is the first item, second and third. They each have an index which they do not share. As the application becomes more complex simple IDs like an index quickly hit their limit, and this is where the concept of a universally unique index comes into play.

In React Native

More specifically when using Expo in React Native. I had difficulty finding a compatible library for generating UUIDs, each was conflicting with expo. Finally I found a solution which boasts many benefits to store in my own module.

UUID Javascript Implementation

Here is an implementation by Bennet Barouch that I ended up using.

About this implementation Barouch says "...this might never float to the top, but I've built on everything mentioned here to produce something twice as fast, portable all environments, including node, and upgraded from Math.random() to crypto-strength randomness. You might not think uuid needs crypto strength, but what that means is even less chance of a collision, which is the entire point of a uuid."

function random() {
const
fourBytesOn = 0xffffffff, // 4 bytes, all 32 bits on: 4294967295
c = typeof crypto === "object"
? crypto // node or most browsers
: typeof msCrypto === "object" // stinky non-standard IE
? msCrypto // eslint-disable-line no-undef
: null; // what old or bad environment are we running in?
return c
? c.randomBytes
? parseInt(c.randomBytes(4).toString("hex"), 16) / (fourBytesOn + 1) - Number.EPSILON // node
: c.getRandomValues(new Uint32Array(1))[0] / (fourBytesOn + 1) - Number.EPSILON // browsers
: Math.random();
}
function uuidV4() { // eslint-disable-line complexity
// if possible, generate a single random value, 128 bits (16 bytes) in length
// in an environment where that is not possible, generate and make use of 4 32-bit (4-byte) random values
// use crypto-grade randomness when available, else Math.random()
const
c = typeof crypto === "object"
? crypto // node or most browsers
: typeof msCrypto === "object" // stinky non-standard IE
? msCrypto // eslint-disable-line no-undef
: null; // what old or bad environment are we running in?
let
byteArray = c
? c.randomBytes
? c.randomBytes(16) // node
: c.getRandomValues(new Uint8Array(16)) // browsers
: null,
uuid = [ ];
/* eslint-disable no-bitwise */
if ( ! byteArray) { // no support for generating 16 random bytes in one shot -- this will be slower
const
int = [
random() * 0xffffffff | 0,
random() * 0xffffffff | 0,
random() * 0xffffffff | 0,
random() * 0xffffffff | 0
];
byteArray = [ ];
for (let i = 0; i < 256; i++) {
byteArray[i] = int[i < 4 ? 0 : i < 8 ? 1 : i < 12 ? 2 : 3] >> i % 4 * 8 & 0xff;
}
}
byteArray[6] = byteArray[6] & 0x0f | 0x40; // always 4, per RFC, indicating the version
byteArray[8] = byteArray[8] & 0x3f | 0x80; // constrained to [89ab], per RFC for version 4
for (let i = 0; i < 16; ++i) {
uuid[i] = (byteArray[i] < 16 ? "0" : "") + byteArray[i].toString(16);
}
uuid =
uuid[ 0] + uuid[ 1] + uuid[ 2] + uuid[ 3] + "-" +
uuid[ 4] + uuid[ 5] + "-" +
uuid[ 6] + uuid[ 7] + "-" +
uuid[ 8] + uuid[ 9] + "-" +
uuid[10] + uuid[11] + uuid[12] + uuid[13] + uuid[14] + uuid[15];
return uuid;
/* eslint-enable no-bitwise */

It is quite thorough and I haven't taken the time to dig through it too deeply yet. But it works great with my Expo application. Thanks Bennet. Here is the Stackoverflow question where the solution is to be found.