简体   繁体   中英

How can you find something inside cloud Firestore when you don't know the key?

Now, consider that I have about a million users with userId (this would probably be a collection)

1234567
1223452
1223454
1223456
1223425
1225451
......
......
......

Now, each collection contains documents, which would look something like this

1234567 
  --- userauth 
  ------ email: any123@gmail.com
1223452
  --- userauth 
  ------ email: varun123@gmail.com
......
......
......

Now, If i want to find userId of a person having a particular email id (Say: any123@gmail.com), how would I do it?

For this question, I am operating inside of a Cloud Function.

Will it be more efficient than SQL?

Update: As answered I did something like this

class docStore() {
 constructor (firestore) {
  this.store = firestore 
 }

async query(collection, condition) {
        let colRef = this.store.collection(collection)
        if (_.isArray(condition)) {
            condition.forEach(predicate => {
                colRef = colRef.where(predicate.name, predicate.op, predicate.value)
            })
        }

        const results = []
        const snapshot = await colRef.get()
        snapshot.forEach(doc => {
            results.push({data: doc.data(), id:doc.id})
        })
        console.notice(results)
        return results
    }

}

Where this.store is admin.firestore()

And my query is this

const checkIfEmailExsist = await docStore.query(SIGNUP_TABLES.userAuth, ['email', '==', userEmail])

Here docStore is above class and I am referencing query inside it

This is giving me following error

[2019-11-01T13:52:36.873Z] (node:94753) UnhandledPromiseRejectionWarning: Error: Value for argument "fieldPath" is not a valid field path. The path cannot be omitted.

Any idea what I could be doing wrong?

Thanks for answering that you were operating inside of Cloud functions, and thus using the admin API. Here's the link again to how to make a query to firestore .

A simple function to demonstrate a query like the one above (I'm assuming a collection called 'users') is here:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

let db = admin.firestore();

exports.doQuery = functions.https.onRequest((request, response) => {
    const queryRef = db.collection('users').where('email', '==', 'any123@gmail.com');

    queryRef.get().then((snap) => {
      if (snap.empty) {
        response.send('no result');
      } else {
        let result = '';
        snap.forEach((doc) => {
          result = result + doc.id + ' => ' + JSON.stringify(doc.data()) + '<br>';
        })
        response.send(result);
      }
    }).catch((err) => { response.send('error'); });

  });

In your example, though you show that there is an intermediate userauth level. Assuming this is a map (and not, say, another collection or something), you can use a FieldPath to have your query traverse the map. That query would look like this, and would still return the entire user document:

    const queryRef = db.collection('userProfiles').where(
      new admin.firestore.FieldPath('userauth','email'), '==', 'any123@gmail.com');

As to the question of efficiency, this type of query (simple equality) will be pretty efficent to execute in firestore, as you get an index on every value by default. More complex queries may be more expensive, and require you to create an index . Also, you are only charged for the documents returned (with a minimum of one document for an empty result set).

Comparison with a SQL database would require actual performance testing, of course, and is a much broader question that would involve the full scope of the types of queries you are making, the full layout of the database, what indexes exist, are there other features (eg constraints) that you want out of the SQL database that aren't provided by firestore, are you optimizing cost, latency, or something else, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM