Skip to content Skip to sidebar Skip to footer

Get Random Documents From Firestore Using Javascript

i have read a documents about random java, swift but JS random document firestore i can't find and I see this problem not yet for JS? swift postsRef.whereField('random', isGreater

Solution 1:

Typescript (remove the types if you use Javascript) version for getting random documents using random integers (and wrap-around). This answer uses Cloud function for testing but essentially you just need to copy the getDocuments function.

exportconst getRandomDoc = functions.https.onRequest(async (req, res): Promise<any> => {
  try {
    const randomDocs = awaitgetDocuments(2)
    return res.send(randomDocs)
  } catch (err) {
    return res.send(err)
  }
});

const getDocuments = async (count: number): Promise<Array<FirebaseFirestore.DocumentData>> => {
  const randomNum = Math.floor(Math.random() * 10000)
  const snapshot = await admin.firestore().collection("col").where("rInt", ">=", randomNum).limit(count).get()
  if (snapshot.empty) {
    returngetDocuments(count)
  }
  return snapshot.docs.map(d => d.data())
}

Whenever you add a new document to that collection, add the rInt field along with it which is an integer between 0 to 10000 (both inclusive). You pass the number of documents you need in the getDoucments function. It will fetch N consecutive matched docs though as this uses limit() method.

In the query we look for documents where rInt is greater than or equal to that random number generated using Math.random() and limit the results to count parameter passed in the function. If the snapshot is empty we retry the function. (It'll be worth to add a logic which makes this function repeat only N number of time else recursion will take it's time).


Using .limit() as in the function above will end up returning N documents in a row. By default, docs will be ordered by their document ID unless you specify any particular field using orderBy method. Instead making a separate request for each doc will increase the randomicity.

/**
 * @param {number} count - number of documents to retrieve
 * @param {number} loopNum - number of times the loop is being repeated. Defaults to 0 
 * @param {Array<any>} curDocs - array of documents matched so far. Defaults to an empty array
 * @returns 
 */const getDocuments = async (count: number, loopNum: number, curDocs: Array<any>): Promise<Array<FirebaseFirestore.DocumentData>> => {
  // Creating an array of requests to get documentsconst requests = []
  for (let i = 0; i < count; i++) {
    // New random number for each requestconst randomNum = Math.floor(Math.random() * 10000)
    console.log(`Random Num: ${randomNum}`);
    requests.push(admin.firestore().collection("col").where("rInt", ">=", randomNum).limit(1).get())
    // limit is set to 1 so each request will return 1 document only
  }
  
  // Using Promise.all() to run all the promisesconst snapshots = awaitPromise.all(requests)
  
  // Removing empty snapshotsconst filteredSnapshots = snapshots.filter(d => !d.empty)

  // Creating an array of doc dataconst matchedDocs = filteredSnapshots.map(doc => doc.docs[0].data())
  
  // If documents received are less than requested,// repeat the functionif (matchedDocs.length !== count) {
    // If the function is repeated 5 times,// return with whatever has matched so farif (loopNum + 1 === 5) {
      console.log("Returning CurDocs")
      return curDocs
    }
    returngetDocuments(count, loopNum + 1, [...curDocs, ...matchedDocs])
  }
  
  // Return if you get requested num of docs in first goreturn snapshots.map(d => d.docs[0].data())
}

// Calling the functiongetDocuments(5, 0, [])

Do note that you can use in operator if you are requesting less than or equal to 10 documents. The in operator combines up to 10 equality (==) clauses on the same field with a logical OR.


For original version (swift) by @Dan McGrath, check this answer.

Post a Comment for "Get Random Documents From Firestore Using Javascript"