admin管理员组

文章数量:1173626

I want to set my document ids on the front end, at the same time I set the doc, so I was wondering if there is a way to generate Firestore IDs, which could look like this:

const theID = firebase.firestore().generateID() // something like this

firebase.firestore().collection('posts').doc(theID).set({
    id: theID,
    ...otherData
})

I could use uuid or some other id generator package, but I'm looking for a Firestore id generator. This SO answer points to some newId method, but I can't find it in the JS SDK... ()

I want to set my document ids on the front end, at the same time I set the doc, so I was wondering if there is a way to generate Firestore IDs, which could look like this:

const theID = firebase.firestore().generateID() // something like this

firebase.firestore().collection('posts').doc(theID).set({
    id: theID,
    ...otherData
})

I could use uuid or some other id generator package, but I'm looking for a Firestore id generator. This SO answer points to some newId method, but I can't find it in the JS SDK... (https://www.npmjs.com/package/firebase)

Share Improve this question edited Jun 13, 2019 at 6:41 samzmann asked Jun 13, 2019 at 6:35 samzmannsamzmann 2,5565 gold badges23 silver badges49 bronze badges
Add a comment  | 

6 Answers 6

Reset to default 23

EDIT: Chris Fischer's answer is more up to date, and using crypto to generate random bytes is probably more secure (although you might have trouble trying to use crypto in non node environments, like React Native for example).

Original Answer:

After asking in the RN Firebase discord chat, I was pointed to this util function deep in the react-native-firebase lib. It's essentially the same function as that the SO answer I mentioned in my question refers too (see the code in firebase-js-sdk here).

Depending on which wrapper you use around Firebase, the ID generation util is not necessarily exported/accessible. So I just copied it in my project as a util function:

export const firestoreAutoId = (): string => {
  const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

  let autoId = ''

  for (let i = 0; i < 20; i++) {
    autoId += CHARS.charAt(
      Math.floor(Math.random() * CHARS.length)
    )
  }
  return autoId
}

Sorry, for the late reply :/ Hope this helps!

Another alternative would be:

  1. Install @google-cloud/firestore npm install @google-cloud/firestore

  2. And then import and use autoId when needed:

import {autoId} from "@google-cloud/firestore/build/src/util";
import {randomBytes} from 'crypto';

export function autoId(): string {
  const chars =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let autoId = '';
  while (autoId.length < 20) {
    const bytes = randomBytes(40);
    bytes.forEach(b => {
      // Length of `chars` is 62. We only take bytes between 0 and 62*4-1
      // (both inclusive). The value is then evenly mapped to indices of `char`
      // via a modulo operation.
      const maxValue = 62 * 4 - 1;
      if (autoId.length < 20 && b <= maxValue) {
        autoId += chars.charAt(b % 62);
      }
    });
  }
  return autoId;
}

Taken from the Firestore Node.js SDK: https://github.com/googleapis/nodejs-firestore/blob/4f4574afaa8cf817d06b5965492791c2eff01ed5/dev/src/util.ts#L52

Do you want to add a new document with a unique id?

See https://firebase.google.com/docs/firestore/manage-data/add-data#add_a_document .

sometimes there isn't a meaningful ID for the document, and it's more convenient to let Cloud Firestore auto-generate an ID for you. You can do this by calling add()

In some cases, it can be useful to create a document reference with an auto-generated ID, then use the reference later. For this use case, you can call doc()

Behind the scenes, .add(...) and .doc().set(...) are completely equivalent, so you can use whichever is more convenient.

add()

    // Add a new document with a generated id.
    db.collection("cities").add({
        name: "Tokyo",
        country: "Japan"
    })
    .then(function(docRef) {
        console.log("Document written with ID: ", docRef.id);
    })
    .catch(function(error) {
        console.error("Error adding document: ", error);
    });test.firestore.js

doc()

    // Add a new document with a generated id.
    var newCityRef = db.collection("cities").doc();
    // later...
    newCityRef.set(data);

I couldn't find how to get access to AutoId.newId() from the firestore library. But, there's actually a more secure way to get an ID from the window.crypto library in the browser (code sample in TypeScript - just remove types for JS).

// Use crypto api to generate random string of given length (in bytes)
// Note that characters are hex bytes - so string is twice as long as
// requested length - but has 8 * bytes bits of entropy.
function generateId(bytes: number): string {
    let result = "";
    // Can't use map as it returns another Uint8Array instead of array
    // of strings.
    for (let byte of crypto.getRandomValues(new Uint8Array(bytes))) {
        result += byte.toString(16);
    }
    return result;
}

Solution based on webcrypto that doesn't require any polyfill, producing the actual Firestore ID format:

function firestoreId() {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    return Array.from(crypto.getRandomValues(new Uint8Array(20))).map(b => chars[b % chars.length]).join('')
}

本文标签: javascriptAccess Firestore ID generator on the front endStack Overflow