Using Dan McGrath's solution from https://stackoverflow.com/a/46801925/3073280 (to generate and query random indexes), I can certainly and definitely get one random document whenever the collection has one or more documents. Put another way, getting one random document is easy.
But, I have difficulty in implementing Dan McGrath's solution to get multiple random (non-duplicated) documents from a collection with certainty. I am referring to Dan McGrath’s rinse and repeat solution.
So, with reference to my pseudo code below, how to get exactly 3 documents* (non duplicated) at random when the collection has 5 documents?
import { Component, OnInit } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { throwError, interval, of }  from 'rxjs';
import { retry, switchMap, mergeMap, take } from 'rxjs/operators';
@Component({
  selector: 'app-firestore',
  templateUrl: './firestore.component.html',
  styleUrls: ['./firestore.component.css']
})
export class FirestoreComponent implements OnInit {
  constructor(private afs: AngularFirestore) {
  } 
  // This is the sample data structure in Firestore with only 5 documents in the collection
  // -Collection name is testRandom
  // --Document Auto ID
  // --- { random: 1 }
  // --Document Auto ID
  // --- { random: 2 }
  // --Document Auto ID
  // --- { random: 4, remark: 'intentionally skip 3' }
  // --Document Auto ID
  // --- { random: 5 }
  // --Document Auto ID
  // --- { random: 7, remark: 'intentionally skip 6' }
  getRandomIntInclusive(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive
  }
  /*
  * This will return one document at random but this will not guarantee return if the random number is 3 or 6
  * */
  selectSingleRandomDocument_byQueryingRandomIndexes() {
    return this.afs.collection<Item>('testRandom',
        ref => ref.where('random', '==', this.getRandomIntInclusive(1,7)).limit(1)
    )
      .valueChanges()
      .pipe(
        mergeMap(doc => {
          if (doc.length > 0) {
            return of(doc);
          } else {
            return throwError('no random document queried because the random number is either 3 or 6, hence throw error so it will retry')
          }
        }),
      )
  }
  /*
  * This will query for 3 documents but it will not guarantee return 3 documents if error thrown
  * */
  rinseAndRepeat() {
    interval(2000)
      .pipe(
        take(3),
        switchMap(val => this.selectSingleRandomDocument_byQueryingRandomIndexes()
            .pipe(retry(5)) // return 5 times if get throwError from singleRandomDocument
        )
      )
      .subscribe();
  }
}
In brief, how to get exactly 3 documents* (non duplicated) at random when the collection has 5 documents?
*Note: In production, it would query for 80 documents at random out of thousands of documents from a collection; hence, please do not suggest reading the whole collection and shuffle the documents randomly then read the top 80 documents.
 
    