简体   繁体   中英

Firebase Firestore: Is there a way to enforce required fields for all documents in a collection?

I am manually adding data for an app I am creating. I have to add many documents to a collection, all of which have to contain the same 5 fields. Is there a way to automatically create these fields when I create a new document in the Firebase console? And to also enforce all documents have those 5 fields (so that I don't make mistakes)?

Additionally, is there a better way to manually adding this data than from the Firebase console? Through JSON for example?

There are two separate questions here. Both have been answered before, but never in a single question, so I'll do that here.

Can you set default values for new documents in a collection?

This is not possible. You will have explicitly write those values into each new document you create.

Can you enforce that new documents in a collection have values for certain fields?

This is possible through the use of Firebase's server-side security rules.

For example, to ensure a document has values for field1 , field2 and field3 , you could use hasAll :

allow write: if resource.data.keys().hasAll(['editor', 'admin']);

One option for setting default values on documents is to implement a cloud function with an onCreate trigger , which will then look at each new document when it is created and add the default value if it does not exist. Note that this isn't perfect, as there will be some non zero time between when the object is created and when the function runs, but it may be sufficient for some cases.

Here's what one such function might look like:

const functions = require('firebase-functions');

exports.setDefaultValueFirestore = functions.firestore.document('defaultDemo/{someDoc}')
    .onCreate(async (snap, context) => {
      if(!('defaultWanted' in snap.data())) {
        return snap.ref.set({
          'defaultWanted': 'my default value'
        }, {merge: true});  
      } else {
        return Promise.resolve();
      }
    });

This will set the defaultWanted field on any document created in /defaultDemo to my default value .

However, it is likely more stable to use the security rules and have the client always supply the needed fields as @Frank suggests if you can.

There is no way to set default value as of today.

You may utilize the is operator to enforce required fields. It will ensure the fields are not null other than using the correct data type. For more info, please refer to Enforcing field types

For example, to ensure a document has user_id , origin is map & has certain properties in origin object, you can use the rule below:

match /requests/{doc} {
    allow create: if (request.auth != null) && 
      request.resource.data.user_id is string &&
      request.resource.data.origin is map && 
      request.resource.data.origin.name is string &&
      request.resource.data.origin.is_pinned is bool;
}

I think it is better than hasAll since hasAll only check if the key exist but does not prevent user from adding null value.


For optional fields but you still want to ensure the data type is correct, you may utilize request.resource.data.get method. For more info, please refer to Enforcing types for optional fields

For example if phone_num field is optional, you can use the following rule to ensure the data type is correct:

match /requests/{doc} {
    allow create: if (request.auth != null) && 
      request.resource.data.user_id is string &&
      request.resource.data.get('phone_num', '') is string;
}

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