From bfe484ab838b41ce9c99e0c74abc5df4bc9b34de Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 19:51:47 +0200 Subject: [PATCH 01/19] Update package.json --- firestore/extend-with-functions/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firestore/extend-with-functions/package.json b/firestore/extend-with-functions/package.json index 527c2188..557df906 100644 --- a/firestore/extend-with-functions/package.json +++ b/firestore/extend-with-functions/package.json @@ -3,8 +3,8 @@ "description": "Cloud Functions and Firestore", "main": "index.js", "dependencies": { - "firebase-functions": "^0.8.1", - "firebase-admin": "^5.4.0", + "firebase-functions": "^1.0.0", + "firebase-admin": "~5.11.0", "@google-cloud/firestore": "^0.8.0" } } From bd4e4be618439202422cae5755a8f7005caacc80 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:03:42 +0200 Subject: [PATCH 02/19] Update index.js --- .../extend-with-functions/functions/index.js | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/firestore/extend-with-functions/functions/index.js b/firestore/extend-with-functions/functions/index.js index e54248d3..8d5f5cd2 100644 --- a/firestore/extend-with-functions/functions/index.js +++ b/firestore/extend-with-functions/functions/index.js @@ -4,8 +4,8 @@ function triggerSpecificDocument() { // [START trigger_specific_document] // Listen for any change on document `marie` in collection `users` exports.myFunctionName = functions.firestore - .document('users/marie').onWrite((event) => { - // ... Your code here + .document('users/marie').onWrite((change, context) => { + // ... Your code here }); // [END trigger_specific_document] } @@ -14,15 +14,15 @@ function triggerNewDocument() { // [START trigger_new_document] exports.createUser = functions.firestore .document('users/{userId}') - .onCreate(event => { - // Get an object representing the document - // e.g. {'name': 'Marie', 'age': 66} - const newValue = event.data.data(); + .onCreate((snao, context) => { + // Get an object representing the document + // e.g. {'name': 'Marie', 'age': 66} + const newValue = snap.data(); - // access a particular field as you would any JS property - const name = newValue.name; + // access a particular field as you would any JS property + const name = newValue.name; - // perform desired operations ... + // perform desired operations ... }); // [END trigger_new_document] } @@ -31,18 +31,18 @@ function triggerDocumentUpdated() { // [START trigger_document_updated] exports.updateUser = functions.firestore .document('users/{userId}') - .onUpdate(event => { - // Get an object representing the document - // e.g. {'name': 'Marie', 'age': 66} - const newValue = event.data.data(); + .onUpdate((change, context) => { + // Get an object representing the document + // e.g. {'name': 'Marie', 'age': 66} + const newValue = change.after.data(); - // ...or the previous value before this update - const previousValue = event.data.previous.data(); + // ...or the previous value before this update + const previousValue = change.before.data(); - // access a particular field as you would any JS property - const name = newValue.name; + // access a particular field as you would any JS property + const name = newValue.name; - // perform desired operations ... + // perform desired operations ... }); // [END trigger_document_updated] } @@ -51,12 +51,12 @@ function triggerDocumentDeleted() { // [START trigger_document_deleted] exports.deleteUser = functions.firestore .document('users/{userID}') - .onDelete(event => { - // Get an object representing the document prior to deletion - // e.g. {'name': 'Marie', 'age': 66} - const deletedValue = event.data.previous.data(); + .onDelete((snap, context) => { + // Get an object representing the document prior to deletion + // e.g. {'name': 'Marie', 'age': 66} + const deletedValue = snap.data(); - // perform desired operations ... + // perform desired operations ... }); // [END trigger_document_deleted] } @@ -65,13 +65,13 @@ function triggerDocumentAnyChange() { // [START trigger_document_any_change] exports.modifyUser = functions.firestore .document('users/{userID}') - .onWrite(event => { + .onWrite((change, context) => { // Get an object with the current document value. // If the document does not exist, it has been deleted. - const document = event.data.exists ? event.data.data() : null; + const document = change.after.exists ? change.after.data() : null; // Get an object with the previous document value (for update or delete) - const oldDocument = event.data.previous.data(); + const oldDocument = change.before.data(); // perform desired operations ... }); @@ -82,24 +82,24 @@ function readingData() { // [START reading_data] exports.updateUser = functions.firestore .document('users/{userId}') - .onUpdate(event => { - // Get an object representing the current document - const newValue = event.data.data(); + .onUpdate((change, context) => { + // Get an object representing the current document + const newValue = change.after.data(); - // ...or the previous value before this update - const previousValue = event.data.previous.data(); + // ...or the previous value before this update + const previousValue = change.after.data(); }); // [END reading_data] } -function readingDataWithGet(event) { +function readingDataWithGet(snap) { // [START reading_data_with_get] // Fetch data using standard accessors - const age = event.data.data().age; - const name = event.data.data()['name']; + const age = snap.data().age; + const name = snap.data()['name']; // Fetch data using built in accessor - const experience = event.data.get('experience'); + const experience = snap.get('experience'); // [END reading_data_with_get] } @@ -108,25 +108,25 @@ function writingData() { // Listen for updates to any `user` document. exports.countNameChanges = functions.firestore .document('users/{userId}') - .onUpdate((event) => { - // Retrieve the current and previous value - const data = event.data.data(); - const previousData = event.data.previous.data(); - - // We'll only update if the name has changed. - // This is crucial to prevent infinite loops. - if (data.name == previousData.name) return; - - // Retrieve the current count of name changes - let count = data.name_change_count; - if (!count) { - count = 0; - } - - // Then return a promise of a set operation to update the count - return event.data.ref.set({ - name_change_count: count + 1 - }, {merge: true}); + .onUpdate((change, context) => { + // Retrieve the current and previous value + const data = change.after.data(); + const previousData = change.before.data(); + + // We'll only update if the name has changed. + // This is crucial to prevent infinite loops. + if (data.name == previousData.name) return; + + // Retrieve the current count of name changes + let count = data.name_change_count; + if (!count) { + count = 0; + } + + // Then return a promise of a set operation to update the count + return change.after.ref.set({ + name_change_count: count + 1 + }, {merge: true}); }); // [END writing_data] } @@ -136,11 +136,11 @@ function basicWildcard() { // Listen for changes in all documents and all sub-collections exports.useWildcard = functions.firestore .document('users/{userId}') - .onWrite((event) => { - // If we set `/users/marie` to {name: "marie"} then - // event.params.userId == "marie" - // ... and ... - // event.data.data() == {name: "Marie"} + .onWrite((change, context) => { + // If we set `/users/marie` to {name: "marie"} then + // context.params.userId == "marie" + // ... and ... + // change.after.data() == {name: "Marie"} }); // [END basic_wildcard] } @@ -150,13 +150,13 @@ function multiWildcard() { // Listen for changes in all documents and all subcollections exports.useMultipleWildcards = functions.firestore .document('users/{userId}/{messageCollectionId}/{messageId}') - .onWrite((event) => { - // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then - // event.params.userId == "marie"; - // event.params.messageCollectionId == "incoming_messages"; - // event.params.messageId == "134"; - // ... and ... - // event.data.data() == {body: "Hello"} + .onWrite((change, context) => { + // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then + // context.params.userId == "marie"; + // context.params.messageCollectionId == "incoming_messages"; + // context.params.messageId == "134"; + // ... and ... + // context.data.data() == {body: "Hello"} }); // [END multi_wildcard] } From e3252668969ecfb00a06f414ffdf708abc058995 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:05:23 +0200 Subject: [PATCH 03/19] Update index.js --- firestore/extend-with-functions/functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore/extend-with-functions/functions/index.js b/firestore/extend-with-functions/functions/index.js index 8d5f5cd2..51b21d9a 100644 --- a/firestore/extend-with-functions/functions/index.js +++ b/firestore/extend-with-functions/functions/index.js @@ -14,7 +14,7 @@ function triggerNewDocument() { // [START trigger_new_document] exports.createUser = functions.firestore .document('users/{userId}') - .onCreate((snao, context) => { + .onCreate((snap, context) => { // Get an object representing the document // e.g. {'name': 'Marie', 'age': 66} const newValue = snap.data(); From 33bc21b3fbc19c3d6057115d126d53441529b72c Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:06:50 +0200 Subject: [PATCH 04/19] Update index.js --- firestore/extend-with-functions/functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore/extend-with-functions/functions/index.js b/firestore/extend-with-functions/functions/index.js index 51b21d9a..28f35136 100644 --- a/firestore/extend-with-functions/functions/index.js +++ b/firestore/extend-with-functions/functions/index.js @@ -87,7 +87,7 @@ function readingData() { const newValue = change.after.data(); // ...or the previous value before this update - const previousValue = change.after.data(); + const previousValue = change.before.data(); }); // [END reading_data] } From 0f049fe8c546662db92d954283337d1ce7a6bf73 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:08:39 +0200 Subject: [PATCH 05/19] Update index.js --- firestore/extend-with-functions/functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore/extend-with-functions/functions/index.js b/firestore/extend-with-functions/functions/index.js index 28f35136..e72ac0ba 100644 --- a/firestore/extend-with-functions/functions/index.js +++ b/firestore/extend-with-functions/functions/index.js @@ -156,7 +156,7 @@ function multiWildcard() { // context.params.messageCollectionId == "incoming_messages"; // context.params.messageId == "134"; // ... and ... - // context.data.data() == {body: "Hello"} + // change.after.data() == {body: "Hello"} }); // [END multi_wildcard] } From 6a3680b13624cefaffc372c7bd27d8b0be51d838 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:15:10 +0200 Subject: [PATCH 06/19] Delete README.md --- firestore/presence/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 firestore/presence/README.md diff --git a/firestore/presence/README.md b/firestore/presence/README.md deleted file mode 100644 index 36b6478e..00000000 --- a/firestore/presence/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Firestore Presence - -Demonstrates using Realtime Database presence with Cloud Firestore. \ No newline at end of file From 85f2bc989ae857c9738a677111f466e1d5bfa511 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:15:23 +0200 Subject: [PATCH 07/19] Delete index.js --- firestore/presence/public/index.js | 126 ----------------------------- 1 file changed, 126 deletions(-) delete mode 100644 firestore/presence/public/index.js diff --git a/firestore/presence/public/index.js b/firestore/presence/public/index.js deleted file mode 100644 index 2d7a65cd..00000000 --- a/firestore/presence/public/index.js +++ /dev/null @@ -1,126 +0,0 @@ -var firebase; - -function rtdb_presence() { - // [START rtdb_presence] - // Fetch the current user's ID from Firebase Authentication. - const uid = firebase.auth().currentUser.uid; - - // Create a reference to this user's specific status node. - // This is where we will store data about being online/offline. - const userStatusDatabaseRef = firebase.database().ref(`/status/${uid}`); - - // We'll create two constants which we will write to - // the Realtime database when this device is offline - // or online. - const isOfflineForDatabase = { - state: 'offline', - last_changed: firebase.database.ServerValue.TIMESTAMP, - }; - - const isOnlineForDatabase = { - state: 'online', - last_changed: firebase.database.ServerValue.TIMESTAMP, - }; - - // Create a reference to the special '.info/connected' path in - // Realtime Database. This path returns `true` when connected - // and `false` when disconnected. - firebase.database().ref('.info/connected').on('value', function (snapshot) { - // If we're not currently connected, don't do anything. - if (snapshot.val() == false) { - return; - } - - // If we are currently connected, then use the 'onDisconnect()' - // method to add a set which will only trigger once this - // client has disconnected by closing the app, - // losing internet, or any other means. - userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function () { - // The promise returned from .onDisconnect().set() will - // resolve as soon as the server acknowledges the onDisconnect() - // request, NOT once we've actually disconnected: - // https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect - - // We can now safely set ourselves as 'online' knowing that the - // server will mark us as offline once we lose connection. - userStatusDatabaseRef.set(isOnlineForDatabase); - }); - }); - // [END rtdb_presence] -} - -function rtdb_and_local_fs_presence() { - // [START rtdb_and_local_fs_presence] - // [START_EXCLUDE] - const uid = firebase.auth().currentUser.uid; - const userStatusDatabaseRef = firebase.database().ref(`/status/${uid}`); - - const isOfflineForDatabase = { - state: 'offline', - last_changed: firebase.database.ServerValue.TIMESTAMP, - }; - - const isOnlineForDatabase = { - state: 'online', - last_changed: firebase.database.ServerValue.TIMESTAMP, - }; - - // [END_EXCLUDE] - const userStatusFirestoreRef = firebase.firestore().doc(`/status/${uid}`); - - // Firestore uses a different server timestamp value, so we'll - // create two more constants for Firestore state. - const isOfflineForFirestore = { - state: 'offline', - last_changed: firebase.firestore.FieldValue.serverTimestamp(), - }; - - const isOnlineForFirestore = { - state: 'online', - last_changed: firebase.firestore.FieldValue.serverTimestamp(), - }; - - firebase.database().ref('.info/connected').on('value', function (snapshot) { - if (snapshot.val() == false) { - // Instead of simply returning, we'll also set Firestore's state - // to 'offline'. This ensures that our Firestore cache is aware - // of the switch to 'offline.' - userStatusFirestoreRef.set(isOfflineForFirestore); - return; - } - - userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function () { - userStatusDatabaseRef.set(isOnlineForDatabase); - - // We'll also add Firestore set here for when we come online. - userStatusFirestoreRef.set(isOnlineForFirestore); - }); - }); - // [END rtdb_and_local_fs_presence] -} - -function fs_listen(userStatusFirestoreRef) { - // [START fs_onsnapshot] - userStatusFirestoreRef.onSnapshot(function (doc) { - const isOnline = doc.data().state == 'online'; - // ... use isOnline - }); - // [END fs_onsnapshot] -} - -function fs_listen_online() { - // [START fs_onsnapshot_online] - firebase.firestore().collection('status') - .where('state', '==', 'online') - .onSnapshot(function (snapshot) { - snapshot.docChanges.forEach(function(change) { - if (change.type === 'added') { - console.log(`User ${change.doc.id} is now online.`); - } - if (change.type === 'removed') { - console.log(`User ${change.doc.id} has gone offline.`); - } - }); - }); - // [END fs_onsnapshot_online] -} \ No newline at end of file From 1dafbd227017b41ce793be96c36af5027916dc63 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:15:32 +0200 Subject: [PATCH 08/19] Delete .gitignore --- firestore/presence/functions/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 firestore/presence/functions/.gitignore diff --git a/firestore/presence/functions/.gitignore b/firestore/presence/functions/.gitignore deleted file mode 100644 index daa60294..00000000 --- a/firestore/presence/functions/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test.js From ee75ea29fe55d7d00d7a3a7c130d13000fe29f67 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:15:40 +0200 Subject: [PATCH 09/19] Delete index.js --- firestore/presence/functions/index.js | 40 --------------------------- 1 file changed, 40 deletions(-) delete mode 100644 firestore/presence/functions/index.js diff --git a/firestore/presence/functions/index.js b/firestore/presence/functions/index.js deleted file mode 100644 index 06e2ed01..00000000 --- a/firestore/presence/functions/index.js +++ /dev/null @@ -1,40 +0,0 @@ -// [START presence_sync_function] -const functions = require('firebase-functions'); -const Firestore = require('@google-cloud/firestore'); - -// Since this code will be running in the Cloud Functions enviornment -// we call initialize Firestore without any arguments because it -// detects authentication from the environment. -const firestore = new Firestore(); - -// Create a new function which is triggered on changes to /status/{uid} -// Note: This is a Realtime Database trigger, *not* Cloud Firestore. -exports.onUserStatusChanged = functions.database - .ref('/status/{uid}').onUpdate((event) => { - // Get the data written to Realtime Database - const eventStatus = event.data.val(); - - // Then use other event data to create a reference to the - // corresponding Firestore document. - const userStatusFirestoreRef = firestore.doc(`status/${event.params.uid}`); - - // It is likely that the Realtime Database change that triggered - // this event has already been overwritten by a fast change in - // online / offline status, so we'll re-read the current data - // and compare the timestamps. - return event.data.ref.once('value').then((statusSnapshot) => { - return statusSnapshot.val(); - }).then((status) => { - console.log(status, eventStatus); - // If the current timestamp for this data is newer than - // the data that triggered this event, we exit this function. - if (status.last_changed > eventStatus.last_changed) return; - - // Otherwise, we convert the last_changed field to a Date - eventStatus.last_changed = new Date(eventStatus.last_changed); - - // ... and write it to Firestore. - return userStatusFirestoreRef.set(eventStatus); - }); - }); -// [END presence_sync_function] \ No newline at end of file From a89569d580a1f5d0c19d66a2a1e3ef5d9695698d Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:15:48 +0200 Subject: [PATCH 10/19] Delete package.json --- firestore/presence/functions/package.json | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 firestore/presence/functions/package.json diff --git a/firestore/presence/functions/package.json b/firestore/presence/functions/package.json deleted file mode 100644 index 0f180f7f..00000000 --- a/firestore/presence/functions/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "presence", - "description": "Presence for Firestore", - "dependencies": { - "firebase-admin": "^5.4.0", - "firebase-functions": "^0.7.0", - "@google-cloud/firestore": "^0.8.0" - }, - "private": true, - "devDependencies": { - "prettier": "^1.6.1" - } -} From 84590de3ad0058dc60f38d9df9b8425933ac86f3 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:25:13 +0200 Subject: [PATCH 11/19] Delete README.md --- firestore/full-text-search/README.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 firestore/full-text-search/README.md diff --git a/firestore/full-text-search/README.md b/firestore/full-text-search/README.md deleted file mode 100644 index b98b45aa..00000000 --- a/firestore/full-text-search/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Firestore Full Text Search - -Demonstrates using Algolia for full text search of Firestore documents. - -## Setup - -Configure your Algolia App ID and API Key: -``` -firebase functions:config:set algolia.app_id=$YOUR_APP_ID -firebase functions:config:set algolia.api_key=$YOUR_ADMIN_KEY -``` \ No newline at end of file From 2f78a7e20e903c9adc671658ed7e47585844a5cf Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:25:22 +0200 Subject: [PATCH 12/19] Delete index.js --- firestore/full-text-search/public/index.js | 59 ---------------------- 1 file changed, 59 deletions(-) delete mode 100644 firestore/full-text-search/public/index.js diff --git a/firestore/full-text-search/public/index.js b/firestore/full-text-search/public/index.js deleted file mode 100644 index ebe8995a..00000000 --- a/firestore/full-text-search/public/index.js +++ /dev/null @@ -1,59 +0,0 @@ -const algoliasearch = require('algoliasearch'); -const ALGOLIA_APP_ID = 'YOUR_APP_ID'; -const ALGOLIA_SEARCH_KEY = 'YOUR_SEARCH_KEY'; - -// To pass lint only -const firebase = undefined; -let index = undefined; - -function searchIndexUnsecure() { - // [START search_index_unsecure] - const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_KEY); - const index = client.initIndex('notes'); - - // Search query - const query = 'Some text'; - - // Perform an Algolia search: - // https://www.algolia.com/doc/api-reference/api-methods/search/ - index - .search({ - query - }) - .then(responses => { - // Response from Algolia: - // https://www.algolia.com/doc/api-reference/api-methods/search/#response-format - console.log(responses.hits); - }); - // [END search_index_unsecure] -} - -function searchIndexSecure() { - // [START search_index_secure] - const projectID = 'YOUR_PROJECT_ID'; - - // Search query - const query = 'Some text'; - - // Use Firebase Authentication to request the underlying token - firebase.auth().currentUser.getIdToken() - .then(token => { - // The token is then passed to our getSearchKey Cloud Function - return fetch(`https://us-central1-${projectID}.cloudfunctions.net/getSearchKey/`, { - headers: { Authorization: `Bearer ${token}` } - }); - }).then(r => { - // The Fetch API returns a stream, which we convert into a JSON object. - return r.json(); - }).then(data => { - // Data will contain the restricted key in the `key` field. - this.algolia.client = algoliasearch(ALGOLIA_APP_ID, data.key); - this.algolia.index = this.algolia.client.initIndex('notes'); - - // Perform the search as usual. - return index.search({query}); - }).then(responses => { - console.log(responses.hits); - }); - // [END search_index_secure] -} \ No newline at end of file From 21fd0209066483c286adc1b5c6af26a3607c8ace Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:25:30 +0200 Subject: [PATCH 13/19] Delete package.json --- firestore/full-text-search/functions/package.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 firestore/full-text-search/functions/package.json diff --git a/firestore/full-text-search/functions/package.json b/firestore/full-text-search/functions/package.json deleted file mode 100644 index b2292577..00000000 --- a/firestore/full-text-search/functions/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "full-text-search", - "description": "Full text search for Firestore", - "dependencies": { - "algoliasearch": "^3.24.0", - "firebase-admin": "^5.4.0", - "firebase-functions": "^0.7.0", - "@google-cloud/firestore": "^0.8.0" - }, - "private": true, - "devDependencies": { - "prettier": "^1.6.1" - } -} From 4d56e2841f9f795348e6ac22e00e59123dbb9911 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:25:38 +0200 Subject: [PATCH 14/19] Delete index.js --- firestore/full-text-search/functions/index.js | 124 ------------------ 1 file changed, 124 deletions(-) delete mode 100644 firestore/full-text-search/functions/index.js diff --git a/firestore/full-text-search/functions/index.js b/firestore/full-text-search/functions/index.js deleted file mode 100644 index a5ae2e47..00000000 --- a/firestore/full-text-search/functions/index.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright 2017 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const functions = require('firebase-functions'); -const algoliasearch = require('algoliasearch'); - -// [START init_algolia] -// Initialize Algolia, requires installing Algolia dependencies: -// https://www.algolia.com/doc/api-client/javascript/getting-started/#install -// -// App ID and API Key are stored in functions config variables -const ALGOLIA_ID = functions.config().algolia.app_id; -const ALGOLIA_ADMIN_KEY = functions.config().algolia.api_key; -const ALGOLIA_SEARCH_KEY = functions.config().algolia.search_key; - -const ALGOLIA_INDEX_NAME = 'notes'; -const client = algoliasearch(ALGOLIA_ID, ALGOLIA_ADMIN_KEY); -// [END init_algolia] - -// [START update_index_function] -// Update the search index every time a blog post is written. -exports.onNoteCreated = functions.firestore.document('notes/{noteId}').onCreate(event => { - // Get the note document - const note = event.data.data(); - - // Add an 'objectID' field which Algolia requires - note.objectID = event.params.noteId; - - // Write to the algolia index - const index = client.initIndex(ALGOLIA_INDEX_NAME); - return index.saveObject(note); -}); -// [END update_index_function] - -// [START get_firebase_user] -const admin = require('firebase-admin'); -admin.initializeApp(functions.config().firebase); - -function getFirebaseUser(req, res, next) { - console.log('Check if request is authorized with Firebase ID token'); - - if (!req.headers.authorization - || !req.headers.authorization.startsWith('Bearer ')) { - console.error( - 'No Firebase ID token was passed as a Bearer token in the Authorization header.', - 'Make sure you authorize your request by providing the following HTTP header:', - 'Authorization: Bearer ' - ); - res.status(403).send('Unauthorized'); - return; - } - - let idToken; - if ( - req.headers.authorization && - req.headers.authorization.startsWith('Bearer ') - ) { - console.log('Found \'Authorization\' header'); - idToken = req.headers.authorization.split('Bearer ')[1]; - } - - admin - .auth() - .verifyIdToken(idToken) - .then(decodedIdToken => { - console.log('ID Token correctly decoded', decodedIdToken); - req.user = decodedIdToken; - next(); - }).catch(error => { - console.error('Error while verifying Firebase ID token:', error); - res.status(403).send('Unauthorized'); - }); -} -// [END get_firebase_user] - -// [START get_algolia_user_token] -// This complex HTTP function will be created as an ExpressJS app: -// https://expressjs.com/en/4x/api.html -const app = require('express')(); - -// We'll enable CORS support to allow the function to be invoked -// from our app client-side. -app.use(require('cors')({ origin: true })); - -// Then we'll also use a special 'getFirebaseUser' middleware which -// verifies the Authorization header and adds a `user` field to the -// incoming request: -// https://gist.github.com/abehaskins/832d6f8665454d0cd99ef08c229afb42 -app.use(getFirebaseUser); - -// Add a route handler to the app to generate the secured key -app.get('/', (req, res) => { - // Create the params object as described in the Algolia documentation: - // https://www.algolia.com/doc/guides/security/api-keys/#generating-api-keys - const params = { - // This filter ensures that only documents where author == user_id will be readable - filters: `author:${req.user.user_id}`, - // We also proxy the user_id as a unique token for this key. - userToken: req.user.user_id - }; - - // Call the Algolia API to generate a unique key based on our search key - const key = client.generateSecuredApiKey(ALGOLIA_SEARCH_KEY, params); - - // Then return this key as {key: '...key'} - res.json({ key }); -}); - -// Finally, pass our ExpressJS app to Cloud Functions as a function -// called 'getSearchKey'; -exports.getSearchKey = functions.https.onRequest(app); -// [END get_algolia_user_token] From 87a191bec0402140d63ed2d74a22d960d3f56c64 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:25:44 +0200 Subject: [PATCH 15/19] Delete .gitignore --- firestore/full-text-search/functions/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 firestore/full-text-search/functions/.gitignore diff --git a/firestore/full-text-search/functions/.gitignore b/firestore/full-text-search/functions/.gitignore deleted file mode 100644 index daa60294..00000000 --- a/firestore/full-text-search/functions/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test.js From 6a7a880dc41ab09576f954464fca69b24540fc20 Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:29:30 +0200 Subject: [PATCH 16/19] Updated indentation --- auth/get_service_account_tokens.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/auth/get_service_account_tokens.js b/auth/get_service_account_tokens.js index d64c16af..d41f8234 100644 --- a/auth/get_service_account_tokens.js +++ b/auth/get_service_account_tokens.js @@ -21,14 +21,14 @@ const serviceAccount = require('path/to/serviceAccountKey.json'); const credential = admin.credential.cert(serviceAccount); credential.getAccessToken().then((accessTokenInfo) => { - const accessToken = accessTokenInfo.access_token; - const expirationTime = accessTokenInfo.expires_in; + const accessToken = accessTokenInfo.access_token; + const expirationTime = accessTokenInfo.expires_in; - // Attach accessToken to HTTPS request in the "Authorization: Bearer" header - // After expirationTime, you must generate a new access token - // [START_EXCLUDE] - console.log(`The token ${accessToken} expires in ${expirationTime}`); - // [END_EXCLUDE] + // Attach accessToken to HTTPS request in the "Authorization: Bearer" header + // After expirationTime, you must generate a new access token + // [START_EXCLUDE] + console.log(`The token ${accessToken} expires in ${expirationTime}`); + // [END_EXCLUDE] }); // [END get_service_account_tokens] From 7aa2115338001e6f2a36b2c51944071e5c7c188d Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:39:16 +0200 Subject: [PATCH 17/19] Updated indentation --- firestore/main/index.js | 1422 +++++++++++++++++++-------------------- 1 file changed, 711 insertions(+), 711 deletions(-) diff --git a/firestore/main/index.js b/firestore/main/index.js index 97d6ae35..5d24211f 100644 --- a/firestore/main/index.js +++ b/firestore/main/index.js @@ -8,62 +8,62 @@ const admin = require('firebase-admin'); var console = {log: debug}; function initializeApp() { - process.env.GCLOUD_PROJECT = 'firestorebeta1test2'; - // [START initialize_app] + process.env.GCLOUD_PROJECT = 'firestorebeta1test2'; + // [START initialize_app] - admin.initializeApp({ - credential: admin.credential.applicationDefault() - }); + admin.initializeApp({ + credential: admin.credential.applicationDefault() + }); - var db = admin.firestore(); + var db = admin.firestore(); - // [END initialize_app] - return db; + // [END initialize_app] + return db; } function initializeAppFunctions() { - process.env.GCLOUD_PROJECT = 'firestorebeta1test2'; - // [START initialize_app_functions] - const functions = require('firebase-functions'); + process.env.GCLOUD_PROJECT = 'firestorebeta1test2'; + // [START initialize_app_functions] + const functions = require('firebase-functions'); - admin.initializeApp(functions.config().firebase); + admin.initializeApp(functions.config().firebase); - var db = admin.firestore(); + var db = admin.firestore(); - // [END initialize_app_functions] - return db; + // [END initialize_app_functions] + return db; } function initializeAppSA() { - // [START initialize_app_service_account] + // [START initialize_app_service_account] - var serviceAccount = require('path/to/serviceAccountKey.json'); + var serviceAccount = require('path/to/serviceAccountKey.json'); - admin.initializeApp({ - credential: admin.credential.cert(serviceAccount) - }); + admin.initializeApp({ + credential: admin.credential.cert(serviceAccount) + }); - var db = admin.firestore(); + var db = admin.firestore(); - // [END initialize_app_service_account] - return db; + // [END initialize_app_service_account] + return db; } function demoInitialize(db) { - // [START demo_initialize] - // Fetch data from Firestore - db.collection('cities').get() - .then(documentSet => { - // Print the ID and contents of each document - documentSet.forEach(doc => { - console.log(doc.id, ' => ', doc.data()); - }); - }) - .catch(err => { - // Error fetching documents - console.log('Error', err); + // [START demo_initialize] + // Fetch data from Firestore + db.collection('cities').get() + .then(documentSet => { + // Print the ID and contents of each document + documentSet.forEach(doc => { + console.log(doc.id, ' => ', doc.data()); }); - // [END demo_initialize] + }) + .catch(err => { + // Error fetching documents + console.log('Error', err); + }); + // [END demo_initialize] } // ============================================================================ @@ -71,60 +71,60 @@ function demoInitialize(db) { // ============================================================================ function quickstartAddData(db) { - // [START add_lovelace] - var docRef = db.collection('users').doc('alovelace'); + // [START add_lovelace] + var docRef = db.collection('users').doc('alovelace'); - var setAda = docRef.set({ - first: 'Ada', - last: 'Lovelace', - born: 1815 - }); - // [END add_lovelace] + var setAda = docRef.set({ + first: 'Ada', + last: 'Lovelace', + born: 1815 + }); + // [END add_lovelace] - // [START add_turing] - var aTuringRef = db.collection('users').doc('aturing'); + // [START add_turing] + var aTuringRef = db.collection('users').doc('aturing'); - var setAlan = aTuringRef.set({ - 'first': 'Alan', - 'middle': 'Mathison', - 'last': 'Turing', - 'born': 1912 - }); - // [END add_turing] + var setAlan = aTuringRef.set({ + 'first': 'Alan', + 'middle': 'Mathison', + 'last': 'Turing', + 'born': 1912 + }); + // [END add_turing] - return Promise.all([setAda, setAlan]); + return Promise.all([setAda, setAlan]); } function quickstartQuery(db) { - // [START quickstart_query] - // Realtime listens are not yet supported in the Node.js SDK - var query = db.collection('users').where('born', '<', 1900) - .get() - .then(snapshot => { - snapshot.forEach(doc => { - console.log(doc.id, '=>', doc.data()); - }); - }) - .catch(err => { - console.log('Error getting documents', err); + // [START quickstart_query] + // Realtime listens are not yet supported in the Node.js SDK + var query = db.collection('users').where('born', '<', 1900) + .get() + .then(snapshot => { + snapshot.forEach(doc => { + console.log(doc.id, '=>', doc.data()); }); - // [END quickstart_query] + }) + .catch(err => { + console.log('Error getting documents', err); + }); + // [END quickstart_query] - return query; + return query; } function quickstartListen(db) { - // [START quickstart_listen] - db.collection('users').get() - .then((snapshot) => { - snapshot.forEach((doc) => { - console.log(doc.id, '=>', doc.data()); - }); - }) - .catch((err) => { - console.log('Error getting documents', err); + // [START quickstart_listen] + db.collection('users').get() + .then((snapshot) => { + snapshot.forEach((doc) => { + console.log(doc.id, '=>', doc.data()); }); - // [END quickstart_listen] + }) + .catch((err) => { + console.log('Error getting documents', err); + }); + // [END quickstart_listen] } // ============================================================================ @@ -132,24 +132,24 @@ function quickstartListen(db) { // ============================================================================ function basicReferences(db) { - // [START doc_ref] - var alovelaceDocumentRef = db.collection('users').doc('alovelace'); - // [END doc_ref] + // [START doc_ref] + var alovelaceDocumentRef = db.collection('users').doc('alovelace'); + // [END doc_ref] - // [START collection_ref] - var usersCollectionRef = db.collection('users'); - // [END collection_ref] + // [START collection_ref] + var usersCollectionRef = db.collection('users'); + // [END collection_ref] } function advancedReferences(db) { - // [START doc_ref_alternate] - var alovelaceDocumentRef = db.doc('users/alovelace'); - // [END doc_ref_alternate] + // [START doc_ref_alternate] + var alovelaceDocumentRef = db.doc('users/alovelace'); + // [END doc_ref_alternate] - // [START subcollection_ref] - var messageRef = db.collection('rooms').doc('roomA') - .collection('messages').doc('message1'); - // [END subcollection_ref] + // [START subcollection_ref] + var messageRef = db.collection('rooms').doc('roomA') + .collection('messages').doc('message1'); + // [END subcollection_ref] } // ============================================================================ @@ -157,283 +157,283 @@ function advancedReferences(db) { // ============================================================================ function setDocument(db) { - // [START set_document] - var data = { - name: 'Los Angeles', - state: 'CA', - country: 'USA' - }; - - // Add a new document in collection "cities" with ID 'LA' - var setDoc = db.collection('cities').doc('LA').set(data); - // [END set_document] - - return setDoc.then(res => { - console.log('Set: ', res); - }); -} + // [START set_document] + var data = { + name: 'Los Angeles', + state: 'CA', + country: 'USA' + }; -function dataTypes(db){ - // [START data_types] - var data = { - stringExample: 'Hello, World!', - booleanExample: true, - numberExample: 3.14159265, - dateExample: new Date('December 10, 1815'), - arrayExample: [5, true, 'hello'], - nullExample: null, - objectExample: { - a: 5, - b: true - } - }; + // Add a new document in collection "cities" with ID 'LA' + var setDoc = db.collection('cities').doc('LA').set(data); + // [END set_document] - var setDoc = db.collection('data').doc('one').set(data); - // [END data_types] + return setDoc.then(res => { + console.log('Set: ', res); + }); +} - return setDoc.then(res => { - console.log('Set: ', res); - }); +function dataTypes(db){ + // [START data_types] + var data = { + stringExample: 'Hello, World!', + booleanExample: true, + numberExample: 3.14159265, + dateExample: new Date('December 10, 1815'), + arrayExample: [5, true, 'hello'], + nullExample: null, + objectExample: { + a: 5, + b: true + } + }; + + var setDoc = db.collection('data').doc('one').set(data); + // [END data_types] + + return setDoc.then(res => { + console.log('Set: ', res); + }); } function addDocument(db) { - // [START add_document] - // Add a new document with a generated id. - var addDoc = db.collection('cities').add({ - name: 'Tokyo', - country: 'Japan' - }).then(ref => { - console.log('Added document with ID: ', ref.id); - }); - // [END add_document] + // [START add_document] + // Add a new document with a generated id. + var addDoc = db.collection('cities').add({ + name: 'Tokyo', + country: 'Japan' + }).then(ref => { + console.log('Added document with ID: ', ref.id); + }); + // [END add_document] - return addDoc.then(res => { - console.log('Add: ', res); - }); + return addDoc.then(res => { + console.log('Add: ', res); + }); } function addDocumentWithId(db) { - var data = { foo: 'bar '}; + var data = { foo: 'bar '}; - // [START add_document_id] - db.collection('cities').doc('new-city-id').set(data); - // [END add_document_id] + // [START add_document_id] + db.collection('cities').doc('new-city-id').set(data); + // [END add_document_id] } function addLater(db) { - // [START add_later] - var newCityRef = db.collection('cities').doc(); + // [START add_later] + var newCityRef = db.collection('cities').doc(); - // Later... - var setDoc = newCityRef.set({ - // ... - }); - // [END add_later] + // Later... + var setDoc = newCityRef.set({ + // ... + }); + // [END add_later] - return setDoc.then(res => { - console.log('Add: ', res); - }); + return setDoc.then(res => { + console.log('Add: ', res); + }); } function updateDocument(db) { - // [START update_document] - var cityRef = db.collection('cities').doc('DC'); + // [START update_document] + var cityRef = db.collection('cities').doc('DC'); - // Set the 'capital' field of the city - var updateSingle = cityRef.update({ capital: true }); - // [END update_document] + // Set the 'capital' field of the city + var updateSingle = cityRef.update({ capital: true }); + // [END update_document] - return Promise.all([updateSingle]).then(res => { - console.log('Update: ', res); - }); + return Promise.all([updateSingle]).then(res => { + console.log('Update: ', res); + }); } function updateDocumentMany(db) { - // [START update_document_many] - var cityRef = db.collection('cities').doc('DC'); + // [START update_document_many] + var cityRef = db.collection('cities').doc('DC'); - var updateMany = cityRef.update({ - name: 'Washington D.C.', - country: 'USA', - capital: true - }); - // [END update_document_many] + var updateMany = cityRef.update({ + name: 'Washington D.C.', + country: 'USA', + capital: true + }); + // [END update_document_many] - return updateMany.then(res => { - console.log('Update: ', res); - }); + return updateMany.then(res => { + console.log('Update: ', res); + }); } function updateCreateIfMissing(db) { - // [START update_create_if_missing] - var cityRef = db.collection('cities').doc('BJ'); + // [START update_create_if_missing] + var cityRef = db.collection('cities').doc('BJ'); - var setWithOptions = cityRef.set({ - capital: true - }, { merge: true }); - // [END update_create_if_missing] + var setWithOptions = cityRef.set({ + capital: true + }, { merge: true }); + // [END update_create_if_missing] - return setWithOptions.then(res => { - console.log('Update: ', res); - }); + return setWithOptions.then(res => { + console.log('Update: ', res); + }); } function updateServerTimestamp(db) { - // Create the object before updating it (racy on first run, oh well) - db.collection('objects').doc('some-id').set({}); + // Create the object before updating it (racy on first run, oh well) + db.collection('objects').doc('some-id').set({}); - // [START update_with_server_timestamp] - // Get the `FieldValue` object - var FieldValue = require('firebase-admin').firestore.FieldValue; + // [START update_with_server_timestamp] + // Get the `FieldValue` object + var FieldValue = require('firebase-admin').firestore.FieldValue; - // Create a document reference - var docRef = db.collection('objects').doc('some-id'); + // Create a document reference + var docRef = db.collection('objects').doc('some-id'); - // Update the timestamp field with the value from the server - var updateTimestamp = docRef.update({ - timestamp: FieldValue.serverTimestamp() - }); - // [END update_with_server_timestamp] + // Update the timestamp field with the value from the server + var updateTimestamp = docRef.update({ + timestamp: FieldValue.serverTimestamp() + }); + // [END update_with_server_timestamp] - return updateTimestamp.then(res => { - console.log('Update: ', res); - }); + return updateTimestamp.then(res => { + console.log('Update: ', res); + }); } function updateDeleteField(db) { - // [START update_delete_field] - // Get the `FieldValue` object - var FieldValue = require('firebase-admin').firestore.FieldValue; + // [START update_delete_field] + // Get the `FieldValue` object + var FieldValue = require('firebase-admin').firestore.FieldValue; - // Create a document reference - var cityRef = db.collection('cities').doc('BJ'); + // Create a document reference + var cityRef = db.collection('cities').doc('BJ'); - // Remove the 'capital' field from the document - var removeCapital = cityRef.update({ - capital: FieldValue.delete() - }); - // [END update_delete_field] + // Remove the 'capital' field from the document + var removeCapital = cityRef.update({ + capital: FieldValue.delete() + }); + // [END update_delete_field] - return removeCapital.then(res => { - console.log('Update: ', res); - }); + return removeCapital.then(res => { + console.log('Update: ', res); + }); } function updateNested(db) { - // [START update_nested] - var initialData = { - name: 'Frank', - age: 12, - favorites: { - food: 'Pizza', - color: 'Blue', - subject: 'recess' - } - }; - - // [START_EXCLUDE] - db.collection('users').doc('Frank').set(initialData); - // [END_EXCLUDE] - var updateNested = db.collection('users').doc('Frank').update({ - age: 13, - favorites: { - color: 'Red' - } - }); - // [END update_nested] - - return updateNested.then(res => { - console.log('Update: ', res); - }); + // [START update_nested] + var initialData = { + name: 'Frank', + age: 12, + favorites: { + food: 'Pizza', + color: 'Blue', + subject: 'recess' + } + }; + + // [START_EXCLUDE] + db.collection('users').doc('Frank').set(initialData); + // [END_EXCLUDE] + var updateNested = db.collection('users').doc('Frank').update({ + age: 13, + favorites: { + color: 'Red' + } + }); + // [END update_nested] + + return updateNested.then(res => { + console.log('Update: ', res); + }); } function deleteDocument(db) { - // [START delete_document] - var deleteDoc = db.collection('cities').doc('DC').delete(); - // [END delete_document] + // [START delete_document] + var deleteDoc = db.collection('cities').doc('DC').delete(); + // [END delete_document] - return deleteDoc.then(res => { - console.log('Delete: ', res); - }); + return deleteDoc.then(res => { + console.log('Delete: ', res); + }); } function transaction(db) { - // [START transaction] - // Initialize document - var cityRef = db.collection('cities').doc('SF'); - var setCity = cityRef.set({ - name: 'San Francisco', - state: 'CA', - country: 'USA', - capital: false, - population: 860000 - }); - - var transaction = db.runTransaction(t => { - return t.get(cityRef) - .then(doc => { - // Add one person to the city population - var newPopulation = doc.data().population + 1; - t.update(cityRef, { population: newPopulation }); - }); - }).then(result => { - console.log('Transaction success!'); - }).catch(err => { - console.log('Transaction failure:', err); - }); - // [END transaction] + // [START transaction] + // Initialize document + var cityRef = db.collection('cities').doc('SF'); + var setCity = cityRef.set({ + name: 'San Francisco', + state: 'CA', + country: 'USA', + capital: false, + population: 860000 + }); + + var transaction = db.runTransaction(t => { + return t.get(cityRef) + .then(doc => { + // Add one person to the city population + var newPopulation = doc.data().population + 1; + t.update(cityRef, { population: newPopulation }); + }); + }).then(result => { + console.log('Transaction success!'); + }).catch(err => { + console.log('Transaction failure:', err); + }); + // [END transaction] - return transaction; + return transaction; } function transactionWithResult(db) { - // [START transaction_with_result] - var cityRef = db.collection('cities').doc('SF'); - var transaction = db.runTransaction(t => { - return t.get(cityRef) - .then(doc => { - var newPopulation = doc.data().population + 1; - if (newPopulation <= 1000000) { - t.update(cityRef, { population: newPopulation }); - return Promise.resolve('Population increased to ' + newPopulation); - } else { - return Promise.reject('Sorry! Population is too big.'); - } - }); - }).then(result => { - console.log('Transaction success', result); - }).catch(err => { - console.log('Transaction failure:', err); - }); - // [END transaction_with_result] + // [START transaction_with_result] + var cityRef = db.collection('cities').doc('SF'); + var transaction = db.runTransaction(t => { + return t.get(cityRef) + .then(doc => { + var newPopulation = doc.data().population + 1; + if (newPopulation <= 1000000) { + t.update(cityRef, { population: newPopulation }); + return Promise.resolve('Population increased to ' + newPopulation); + } else { + return Promise.reject('Sorry! Population is too big.'); + } + }); + }).then(result => { + console.log('Transaction success', result); + }).catch(err => { + console.log('Transaction failure:', err); + }); + // [END transaction_with_result] - return transaction; + return transaction; } function updateBatch(db) { - // [START update_data_batch] - // Get a new write batch - var batch = db.batch(); + // [START update_data_batch] + // Get a new write batch + var batch = db.batch(); - // Set the value of 'NYC' - var nycRef = db.collection('cities').doc('NYC'); - batch.set(nycRef, { name: 'New York City' }); + // Set the value of 'NYC' + var nycRef = db.collection('cities').doc('NYC'); + batch.set(nycRef, { name: 'New York City' }); - // Update the population of 'SF' - var sfRef = db.collection('cities').doc('SF'); - batch.update(sfRef, { population: 1000000 }); + // Update the population of 'SF' + var sfRef = db.collection('cities').doc('SF'); + batch.update(sfRef, { population: 1000000 }); - // Delete the city 'LA' - var laRef = db.collection('cities').doc('LA'); - batch.delete(laRef); + // Delete the city 'LA' + var laRef = db.collection('cities').doc('LA'); + batch.delete(laRef); - // Commit the batch - return batch.commit().then(function () { - // [START_EXCLUDE] - console.log('Batched.'); - // [END_EXCLUDE] - }); - // [END update_data_batch] + // Commit the batch + return batch.commit().then(function () { + // [START_EXCLUDE] + console.log('Batched.'); + // [END_EXCLUDE] + }); + // [END update_data_batch] } // ============================================================================ @@ -441,129 +441,129 @@ function updateBatch(db) { // ============================================================================ function exampleData(db) { - // [START example_data] - var citiesRef = db.collection('cities'); - - var setSf = citiesRef.doc('SF').set({ - name: 'San Francisco', state: 'CA', country: 'USA', - capital: false, population: 860000 }); - var setLa = citiesRef.doc('LA').set({ - name: 'Los Angeles', state: 'CA', country: 'USA', - capital: false, population: 3900000 }); - var setDc = citiesRef.doc('DC').set({ - name: 'Washington, D.C.', state: null, country: 'USA', - capital: true, population: 680000 }); - var setTok = citiesRef.doc('TOK').set({ - name: 'Tokyo', state: null, country: 'Japan', - capital: true, population: 9000000 }); - var setBj = citiesRef.doc('BJ').set({ - name: 'Beijing', state: null, country: 'China', - capital: true, population: 21500000 }); - // [END example_data] - - return Promise.all([setSf, setLa, setDc, setTok, setBj]); + // [START example_data] + var citiesRef = db.collection('cities'); + + var setSf = citiesRef.doc('SF').set({ + name: 'San Francisco', state: 'CA', country: 'USA', + capital: false, population: 860000 }); + var setLa = citiesRef.doc('LA').set({ + name: 'Los Angeles', state: 'CA', country: 'USA', + capital: false, population: 3900000 }); + var setDc = citiesRef.doc('DC').set({ + name: 'Washington, D.C.', state: null, country: 'USA', + capital: true, population: 680000 }); + var setTok = citiesRef.doc('TOK').set({ + name: 'Tokyo', state: null, country: 'Japan', + capital: true, population: 9000000 }); + var setBj = citiesRef.doc('BJ').set({ + name: 'Beijing', state: null, country: 'China', + capital: true, population: 21500000 }); + // [END example_data] + + return Promise.all([setSf, setLa, setDc, setTok, setBj]); } function exampleDataTwo(db) { - // [START example_data_two] - var citiesRef = db.collection('cities'); - - var setSf = citiesRef.doc('SF').set({ - name: 'San Francisco', state: 'CA', country: 'USA', - capital: false, population: 860000 }); - var setLa = citiesRef.doc('LA').set({ - name: 'Los Angeles', state: 'CA', country: 'USA', - capital: false, population: 3900000 }); - var setDc = citiesRef.doc('DC').set({ - name: 'Washington, D.C.', state: null, country: 'USA', - capital: true, population: 680000 }); - var setTok = citiesRef.doc('TOK').set({ - name: 'Tokyo', state: null, country: 'Japan', - capital: true, population: 9000000 }); - var setBj = citiesRef.doc('BJ').set({ - name: 'Beijing', state: null, country: 'China', - capital: true, population: 21500000 }); - // [END example_data_two] - - return Promise.all([setSf, setLa, setDc, setTok, setBj]); + // [START example_data_two] + var citiesRef = db.collection('cities'); + + var setSf = citiesRef.doc('SF').set({ + name: 'San Francisco', state: 'CA', country: 'USA', + capital: false, population: 860000 }); + var setLa = citiesRef.doc('LA').set({ + name: 'Los Angeles', state: 'CA', country: 'USA', + capital: false, population: 3900000 }); + var setDc = citiesRef.doc('DC').set({ + name: 'Washington, D.C.', state: null, country: 'USA', + capital: true, population: 680000 }); + var setTok = citiesRef.doc('TOK').set({ + name: 'Tokyo', state: null, country: 'Japan', + capital: true, population: 9000000 }); + var setBj = citiesRef.doc('BJ').set({ + name: 'Beijing', state: null, country: 'China', + capital: true, population: 21500000 }); + // [END example_data_two] + + return Promise.all([setSf, setLa, setDc, setTok, setBj]); } function getDocument(db) { - // [START get_document] - var cityRef = db.collection('cities').doc('SF'); - var getDoc = cityRef.get() - .then(doc => { - if (!doc.exists) { - console.log('No such document!'); - } else { - console.log('Document data:', doc.data()); - } - }) - .catch(err => { - console.log('Error getting document', err); - }); - // [END get_document] + // [START get_document] + var cityRef = db.collection('cities').doc('SF'); + var getDoc = cityRef.get() + .then(doc => { + if (!doc.exists) { + console.log('No such document!'); + } else { + console.log('Document data:', doc.data()); + } + }) + .catch(err => { + console.log('Error getting document', err); + }); + // [END get_document] - return getDoc; + return getDoc; } function getDocumentEmpty(db) { - var cityRef = db.collection('cities').doc('Amexico'); - var getDoc = cityRef.get() - .then(doc => { - if (!doc.exists) { - console.log('No such document!'); - } else { - console.log('Document data:', doc.data()); - } - }); + var cityRef = db.collection('cities').doc('Amexico'); + var getDoc = cityRef.get() + .then(doc => { + if (!doc.exists) { + console.log('No such document!'); + } else { + console.log('Document data:', doc.data()); + } + }); - return getDoc; + return getDoc; } function getMultiple(db) { - // [START get_multiple] - var citiesRef = db.collection('cities'); - var query = citiesRef.where('capital', '==', true).get() - .then(snapshot => { - snapshot.forEach(doc => { - console.log(doc.id, '=>', doc.data()); - }); - }) - .catch(err => { - console.log('Error getting documents', err); + // [START get_multiple] + var citiesRef = db.collection('cities'); + var query = citiesRef.where('capital', '==', true).get() + .then(snapshot => { + snapshot.forEach(doc => { + console.log(doc.id, '=>', doc.data()); }); - // [END get_multiple] + }) + .catch(err => { + console.log('Error getting documents', err); + }); + // [END get_multiple] - return query; + return query; } function getAll(db) { - // [START get_all] - var citiesRef = db.collection('cities'); - var allCities = citiesRef.get() - .then(snapshot => { - snapshot.forEach(doc => { - console.log(doc.id, '=>', doc.data()); - }); - }) - .catch(err => { - console.log('Error getting documents', err); + // [START get_all] + var citiesRef = db.collection('cities'); + var allCities = citiesRef.get() + .then(snapshot => { + snapshot.forEach(doc => { + console.log(doc.id, '=>', doc.data()); }); - // [END get_all] + }) + .catch(err => { + console.log('Error getting documents', err); + }); + // [END get_all] - return allCities; + return allCities; } function getCollections(db) { - // [START get_collections] - var sfRef = db.collection('cities').doc('SF'); - sfRef.getCollections().then(collections => { - collections.forEach(collection => { - console.log('Found subcollection with id:', collection.id); - }); + // [START get_collections] + var sfRef = db.collection('cities').doc('SF'); + sfRef.getCollections().then(collections => { + collections.forEach(collection => { + console.log('Found subcollection with id:', collection.id); }); - // [END get_collections] + }); + // [END get_collections] } // ============================================================================ @@ -571,151 +571,151 @@ function getCollections(db) { // ============================================================================ function simpleQuery(db) { - // [START simple_query] - // Create a reference to the cities collection - var citiesRef = db.collection('cities'); + // [START simple_query] + // Create a reference to the cities collection + var citiesRef = db.collection('cities'); - // Create a query against the collection - var queryRef = citiesRef.where('state', '==', 'CA'); - // [END simple_query] + // Create a query against the collection + var queryRef = citiesRef.where('state', '==', 'CA'); + // [END simple_query] - return simpleQuery.get(); + return simpleQuery.get(); } function queryAndFilter(db) { - // [START create_query] - // Create a reference to the cities collection - var citiesRef = db.collection('cities'); - - // Create a query against the collection - var queryRef = citiesRef.where('capital', '==', true); - // [END create_query] - - // [START example_filters] - var brazilCities = citiesRef.where('state', '==', 'CA'); - var smallCities = citiesRef.where('population', '<', 1000000); - var afterParis = citiesRef.where('name', '>=', 'San Francisco'); - // [END example_filters] - - return Promise.all([brazilCities.get(), smallCities.get(), afterParis.get()]).then(res => { - res.forEach(r => { - r.forEach(d => { - console.log('Get:', d); - }); - console.log(); - }); + // [START create_query] + // Create a reference to the cities collection + var citiesRef = db.collection('cities'); + + // Create a query against the collection + var queryRef = citiesRef.where('capital', '==', true); + // [END create_query] + + // [START example_filters] + var brazilCities = citiesRef.where('state', '==', 'CA'); + var smallCities = citiesRef.where('population', '<', 1000000); + var afterParis = citiesRef.where('name', '>=', 'San Francisco'); + // [END example_filters] + + return Promise.all([brazilCities.get(), smallCities.get(), afterParis.get()]).then(res => { + res.forEach(r => { + r.forEach(d => { + console.log('Get:', d); + }); + console.log(); }); + }); } function orderAndLimit(db) { - var citiesRef = db.collection('cities'); - // [START order_limit] - var firstThree = citiesRef.orderBy('name').limit(3); - // [END order_limit] - - // [START order_limit_desc] - var lastThree = citiesRef.orderBy('name', 'desc').limit(3); - // [END order_limit_desc] - - // [START order_multi_field] - var byStateByPop = citiesRef.orderBy('state').orderBy('population', 'desc'); - // [END order_multi_field] - - // [START where_and_order] - var biggest = citiesRef.where('population', '>', 2500000).orderBy('population').limit(2); - // [END where_and_order] - - return Promise.all([firstThree.get(), lastThree.get(), biggest.get()]).then(res => { - res.forEach(r => { - r.forEach(d => { - console.log('Get:', d); - }); - console.log(); - }); + var citiesRef = db.collection('cities'); + // [START order_limit] + var firstThree = citiesRef.orderBy('name').limit(3); + // [END order_limit] + + // [START order_limit_desc] + var lastThree = citiesRef.orderBy('name', 'desc').limit(3); + // [END order_limit_desc] + + // [START order_multi_field] + var byStateByPop = citiesRef.orderBy('state').orderBy('population', 'desc'); + // [END order_multi_field] + + // [START where_and_order] + var biggest = citiesRef.where('population', '>', 2500000).orderBy('population').limit(2); + // [END where_and_order] + + return Promise.all([firstThree.get(), lastThree.get(), biggest.get()]).then(res => { + res.forEach(r => { + r.forEach(d => { + console.log('Get:', d); + }); + console.log(); }); + }); } function validInvalidQueries(db) { - var citiesRef = db.collection('cities'); + var citiesRef = db.collection('cities'); - // [START valid_chained] - citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver'); - // [END valid_chained] + // [START valid_chained] + citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver'); + // [END valid_chained] - // [START invalid_chained] - citiesRef.where('state', '==', 'CA').where('population', '<', 1000000); - // [END invalid_chained] + // [START invalid_chained] + citiesRef.where('state', '==', 'CA').where('population', '<', 1000000); + // [END invalid_chained] - // [START valid_range] - citiesRef.where('state', '>=', 'CA').where('state', '<=', 'IN'); - citiesRef.where('state', '==', 'CA').where('population', '>', 1000000); - // [END valid_range] + // [START valid_range] + citiesRef.where('state', '>=', 'CA').where('state', '<=', 'IN'); + citiesRef.where('state', '==', 'CA').where('population', '>', 1000000); + // [END valid_range] - // [START invalid_range] - citiesRef.where('state', '>=', 'CA').where('population', '>', 1000000); - // [END invalid_range] + // [START invalid_range] + citiesRef.where('state', '>=', 'CA').where('population', '>', 1000000); + // [END invalid_range] - // [START valid_order_by] - citiesRef.where('population', '>', 2500000).orderBy('population'); - // [END valid_order_by] + // [START valid_order_by] + citiesRef.where('population', '>', 2500000).orderBy('population'); + // [END valid_order_by] - // [START invalid_order_by] - citiesRef.where('population', '>', 2500000).orderBy('country'); - // [END invalid_order_by] + // [START invalid_order_by] + citiesRef.where('population', '>', 2500000).orderBy('country'); + // [END invalid_order_by] } function streamSnapshot(db, done) { - // [START query_realtime] - var query = db.collection('cities').where('state', '==', 'CA'); + // [START query_realtime] + var query = db.collection('cities').where('state', '==', 'CA'); - var observer = query.onSnapshot(querySnapshot => { - console.log(`Received query snapshot of size ${querySnapshot.size}`); - // [START_EXCLUDE] - observer(); - done(); - // [END_EXCLUDE] - }, err => { - console.log(`Encountered error: ${err}`); - }); - // [END query_realtime] + var observer = query.onSnapshot(querySnapshot => { + console.log(`Received query snapshot of size ${querySnapshot.size}`); + // [START_EXCLUDE] + observer(); + done(); + // [END_EXCLUDE] + }, err => { + console.log(`Encountered error: ${err}`); + }); + // [END query_realtime] } function streamDocument(db, done) { - // [START doc_realtime] - var doc = db.collection('cities').doc('SF'); + // [START doc_realtime] + var doc = db.collection('cities').doc('SF'); - var observer = doc.onSnapshot(docSnapshot => { - console.log(`Received doc snapshot: ${docSnapshot}`); - // [START_EXCLUDE] - observer(); - done(); - // [END_EXCLUDE] - }, err => { - console.log(`Encountered error: ${err}`); - }); - // [END doc_realtime] + var observer = doc.onSnapshot(docSnapshot => { + console.log(`Received doc snapshot: ${docSnapshot}`); + // [START_EXCLUDE] + observer(); + done(); + // [END_EXCLUDE] + }, err => { + console.log(`Encountered error: ${err}`); + }); + // [END doc_realtime] } function detatchListener(db) { - // [START detach_listener] - var unsub = db.collection('cities').onSnapshot(() => {}); + // [START detach_listener] + var unsub = db.collection('cities').onSnapshot(() => {}); - // ... + // ... - // Stop listening for changes - unsub(); - // [END detach_listener] + // Stop listening for changes + unsub(); + // [END detach_listener] } function listenErrors(db) { - // [START listen_errors] - db.collection('cities') - .onSnapshot((snapshot) => { - //... - }, (error) => { - //... - }); - // [END listen_errors] + // [START listen_errors] + db.collection('cities') + .onSnapshot((snapshot) => { + //... + }, (error) => { + //... + }); + // [END listen_errors] } // ============================================================================ @@ -723,120 +723,120 @@ function listenErrors(db) { // ============================================================================ function simpleCursors(db) { - // [START cursor_simple_start_at] - var startAt = db.collection('cities') - .orderBy('population') - .startAt(1000000); - // [END cursor_simple_start_at] + // [START cursor_simple_start_at] + var startAt = db.collection('cities') + .orderBy('population') + .startAt(1000000); + // [END cursor_simple_start_at] - // [START cursor_simple_end_at] - var endAt = db.collection('cities') - .orderBy('population') - .endAt(1000000); - // [END cursor_simple_end_at] + // [START cursor_simple_end_at] + var endAt = db.collection('cities') + .orderBy('population') + .endAt(1000000); + // [END cursor_simple_end_at] - return Promise.all([ - startAt.limit(10).get(), - endAt.limit(10).get() - ]); + return Promise.all([ + startAt.limit(10).get(), + endAt.limit(10).get() + ]); } function paginateQuery(db) { - // [START cursor_paginate] - var first = db.collection('cities') - .orderBy('population') - .limit(3); - - var paginate = first.get() - .then((snapshot) => { - // ... - - // Get the last document - var last = snapshot.docs[snapshot.docs.length - 1]; - - // Construct a new query starting at this document. - // Note: this will not have the desired effect if multiple - // cities have the exact same population value. - var next = db.collection('cities') - .orderBy('population') - .startAfter(last.data().population) - .limit(3); - - // Use the query for pagination - // [START_EXCLUDE] - return next.get().then((snapshot) => { - console.log('Num results:', snapshot.docs.length); - }); - // [END_EXCLUDE] + // [START cursor_paginate] + var first = db.collection('cities') + .orderBy('population') + .limit(3); + + var paginate = first.get() + .then((snapshot) => { + // ... + + // Get the last document + var last = snapshot.docs[snapshot.docs.length - 1]; + + // Construct a new query starting at this document. + // Note: this will not have the desired effect if multiple + // cities have the exact same population value. + var next = db.collection('cities') + .orderBy('population') + .startAfter(last.data().population) + .limit(3); + + // Use the query for pagination + // [START_EXCLUDE] + return next.get().then((snapshot) => { + console.log('Num results:', snapshot.docs.length); }); - // [END cursor_paginate] + // [END_EXCLUDE] + }); + // [END cursor_paginate] - return paginate; + return paginate; } function multipleCursorConditions(db) { - // [START cursor_multiple_one_start] - // Will return all Springfields - var startAtName = db.collection('cities') - .orderBy('name') - .orderBy('state') - .startAt('Springfield'); - // [END cursor_multiple_one_start] - - // [START cursor_multiple_two_start] - // Will return 'Springfield, Missouri' and 'Springfield, Wisconsin' - var startAtNameAndState = db.collection('cities') - .orderBy('name') - .orderBy('state') - .startAt('Springfield', 'Missouri'); - // [END cursor_multiple_two_start] - - return Promise.all([ - startAtName.get(), - startAtNameAndState.get() - ]); + // [START cursor_multiple_one_start] + // Will return all Springfields + var startAtName = db.collection('cities') + .orderBy('name') + .orderBy('state') + .startAt('Springfield'); + // [END cursor_multiple_one_start] + + // [START cursor_multiple_two_start] + // Will return 'Springfield, Missouri' and 'Springfield, Wisconsin' + var startAtNameAndState = db.collection('cities') + .orderBy('name') + .orderBy('state') + .startAt('Springfield', 'Missouri'); + // [END cursor_multiple_two_start] + + return Promise.all([ + startAtName.get(), + startAtNameAndState.get() + ]); } // [START delete_collection] function deleteCollection(db, collectionPath, batchSize) { - var collectionRef = db.collection(collectionPath); - var query = collectionRef.orderBy('__name__').limit(batchSize); + var collectionRef = db.collection(collectionPath); + var query = collectionRef.orderBy('__name__').limit(batchSize); - return new Promise((resolve, reject) => { - deleteQueryBatch(db, query, batchSize, resolve, reject); - }); + return new Promise((resolve, reject) => { + deleteQueryBatch(db, query, batchSize, resolve, reject); + }); } function deleteQueryBatch(db, query, batchSize, resolve, reject) { - query.get() - .then((snapshot) => { - // When there are no documents left, we are done - if (snapshot.size == 0) { - return 0; - } - - // Delete documents in a batch - var batch = db.batch(); - snapshot.docs.forEach((doc) => { - batch.delete(doc.ref); - }); - - return batch.commit().then(() => { - return snapshot.size; - }); - }).then((numDeleted) => { - if (numDeleted === 0) { - resolve(); - return; - } - - // Recurse on the next process tick, to avoid - // exploding the stack. - process.nextTick(() => { - deleteQueryBatch(db, query, batchSize, resolve, reject); - }); - }) - .catch(reject); + query.get() + .then((snapshot) => { + // When there are no documents left, we are done + if (snapshot.size == 0) { + return 0; + } + + // Delete documents in a batch + var batch = db.batch(); + snapshot.docs.forEach((doc) => { + batch.delete(doc.ref); + }); + + return batch.commit().then(() => { + return snapshot.size; + }); + }).then((numDeleted) => { + if (numDeleted === 0) { + resolve(); + return; + } + + // Recurse on the next process tick, to avoid + // exploding the stack. + process.nextTick(() => { + deleteQueryBatch(db, query, batchSize, resolve, reject); + }); + }) + .catch(reject); } // [END delete_collection] @@ -845,144 +845,144 @@ function deleteQueryBatch(db, query, batchSize, resolve, reject) { // ============================================================================ describe('Firestore Smoketests', () => { - var db; + var db; - before(() => { - var serviceAccount = require('../../service-account.json'); - admin.initializeApp({ - credential: admin.credential.cert(serviceAccount) - }); - db = admin.firestore(); + before(() => { + var serviceAccount = require('../../service-account.json'); + admin.initializeApp({ + credential: admin.credential.cert(serviceAccount) }); + db = admin.firestore(); + }); - it('should get an empty document', () => { - return getDocumentEmpty(db); - }); + it('should get an empty document', () => { + return getDocumentEmpty(db); + }); - it('should delete existing documents', () => { - return deleteCollection(db, 'cities', 50); - }); + it('should delete existing documents', () => { + return deleteCollection(db, 'cities', 50); + }); - it('should store example data', () => { - return exampleData(db); - }); + it('should store example data', () => { + return exampleData(db); + }); - it('should add quickstart data', () => { - return quickstartAddData(db); - }); + it('should add quickstart data', () => { + return quickstartAddData(db); + }); - it('should query quickstart data', () => { - return quickstartQuery(db); - }); + it('should query quickstart data', () => { + return quickstartQuery(db); + }); - it('should set a document', () => { - return setDocument(db); - }); + it('should set a document', () => { + return setDocument(db); + }); - it('should manage data types', () => { - return dataTypes(db); - }); + it('should manage data types', () => { + return dataTypes(db); + }); - it('should add a document', () => { - return addDocument(db); - }); + it('should add a document', () => { + return addDocument(db); + }); - it('should add a document later', () => { - return addLater(db); - }); + it('should add a document later', () => { + return addLater(db); + }); - it('should update a document', () => { - return updateDocument(db); - }); + it('should update a document', () => { + return updateDocument(db); + }); - it('should update many document', () => { - return updateDocumentMany(db); - }); + it('should update many document', () => { + return updateDocumentMany(db); + }); - it('should update a missing doc', () => { - return updateCreateIfMissing(db); - }); + it('should update a missing doc', () => { + return updateCreateIfMissing(db); + }); - it('should update with server timestamp', () => { - return updateServerTimestamp(db); - }); + it('should update with server timestamp', () => { + return updateServerTimestamp(db); + }); - it('should handle transactions', () => { - return transaction(db); - }); + it('should handle transactions', () => { + return transaction(db); + }); - it('should handle transaction with a result', () => { - return transactionWithResult(db).then(res => { - // Delete data set - return deleteCollection(db, 'cities', 50); - }); + it('should handle transaction with a result', () => { + return transactionWithResult(db).then(res => { + // Delete data set + return deleteCollection(db, 'cities', 50); }); + }); - it('should set more example data', () => { - return exampleDataTwo(db); - }); + it('should set more example data', () => { + return exampleDataTwo(db); + }); - it('should get document', () => { - return getDocument(db); - }); + it('should get document', () => { + return getDocument(db); + }); - it('should get multiple documents', () => { - return getMultiple(db); - }); + it('should get multiple documents', () => { + return getMultiple(db); + }); - it('should get all documents', () => { - return getAll(db); - }); + it('should get all documents', () => { + return getAll(db); + }); - it('should get all subcollections of a document', () => { - return getCollections(db); - }); + it('should get all subcollections of a document', () => { + return getCollections(db); + }); - it('should query and filter', () => { - return queryAndFilter(db); - }); + it('should query and filter', () => { + return queryAndFilter(db); + }); - it('should order and limit', () => { - return orderAndLimit(db); - }); + it('should order and limit', () => { + return orderAndLimit(db); + }); - it('should update and delete a field', () => { - return updateDeleteField(db); - }); + it('should update and delete a field', () => { + return updateDeleteField(db); + }); - it('should update nested fields', () => { - return updateNested(db); - }); + it('should update nested fields', () => { + return updateNested(db); + }); - it('should update in a batch', () => { - updateBatch(db); - }); + it('should update in a batch', () => { + updateBatch(db); + }); - it('should delete doucment', () => { - return deleteDocument(db); - }); + it('should delete doucment', () => { + return deleteDocument(db); + }); - it('should stream query data', (done) => { - return streamSnapshot(db, done); - }); + it('should stream query data', (done) => { + return streamSnapshot(db, done); + }); - it('should stream doc data', (done) => { - return streamDocument(db, done); - }); + it('should stream doc data', (done) => { + return streamDocument(db, done); + }); - it('should support simple cursors', () => { - return simpleCursors(db); - }); + it('should support simple cursors', () => { + return simpleCursors(db); + }); - it('should support pagination', () => { - return paginateQuery(db); - }); + it('should support pagination', () => { + return paginateQuery(db); + }); - it('should support multiple cursor conditions', () => { - return multipleCursorConditions(db); - }); + it('should support multiple cursor conditions', () => { + return multipleCursorConditions(db); + }); - it('should delete the whole collection', () => { - return deleteCollection(db, 'cities', 50); - }); -}); \ No newline at end of file + it('should delete the whole collection', () => { + return deleteCollection(db, 'cities', 50); + }); +}); From 30c7af030a033540e9b5c752104ca73ca7806e7b Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:40:14 +0200 Subject: [PATCH 18/19] Corrected indentation --- .../extend-with-functions/functions/index.js | 262 +++++++++--------- 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/firestore/extend-with-functions/functions/index.js b/firestore/extend-with-functions/functions/index.js index e72ac0ba..d3013c85 100644 --- a/firestore/extend-with-functions/functions/index.js +++ b/firestore/extend-with-functions/functions/index.js @@ -1,162 +1,162 @@ const functions = require('firebase-functions'); function triggerSpecificDocument() { - // [START trigger_specific_document] - // Listen for any change on document `marie` in collection `users` - exports.myFunctionName = functions.firestore - .document('users/marie').onWrite((change, context) => { - // ... Your code here - }); - // [END trigger_specific_document] + // [START trigger_specific_document] + // Listen for any change on document `marie` in collection `users` + exports.myFunctionName = functions.firestore + .document('users/marie').onWrite((change, context) => { + // ... Your code here + }); + // [END trigger_specific_document] } function triggerNewDocument() { - // [START trigger_new_document] - exports.createUser = functions.firestore - .document('users/{userId}') - .onCreate((snap, context) => { - // Get an object representing the document - // e.g. {'name': 'Marie', 'age': 66} - const newValue = snap.data(); - - // access a particular field as you would any JS property - const name = newValue.name; - - // perform desired operations ... - }); - // [END trigger_new_document] + // [START trigger_new_document] + exports.createUser = functions.firestore + .document('users/{userId}') + .onCreate((snap, context) => { + // Get an object representing the document + // e.g. {'name': 'Marie', 'age': 66} + const newValue = snap.data(); + + // access a particular field as you would any JS property + const name = newValue.name; + + // perform desired operations ... + }); + // [END trigger_new_document] } function triggerDocumentUpdated() { - // [START trigger_document_updated] - exports.updateUser = functions.firestore - .document('users/{userId}') - .onUpdate((change, context) => { - // Get an object representing the document - // e.g. {'name': 'Marie', 'age': 66} - const newValue = change.after.data(); - - // ...or the previous value before this update - const previousValue = change.before.data(); - - // access a particular field as you would any JS property - const name = newValue.name; - - // perform desired operations ... - }); - // [END trigger_document_updated] + // [START trigger_document_updated] + exports.updateUser = functions.firestore + .document('users/{userId}') + .onUpdate((change, context) => { + // Get an object representing the document + // e.g. {'name': 'Marie', 'age': 66} + const newValue = change.after.data(); + + // ...or the previous value before this update + const previousValue = change.before.data(); + + // access a particular field as you would any JS property + const name = newValue.name; + + // perform desired operations ... + }); + // [END trigger_document_updated] } function triggerDocumentDeleted() { - // [START trigger_document_deleted] - exports.deleteUser = functions.firestore - .document('users/{userID}') - .onDelete((snap, context) => { - // Get an object representing the document prior to deletion - // e.g. {'name': 'Marie', 'age': 66} - const deletedValue = snap.data(); - - // perform desired operations ... - }); - // [END trigger_document_deleted] + // [START trigger_document_deleted] + exports.deleteUser = functions.firestore + .document('users/{userID}') + .onDelete((snap, context) => { + // Get an object representing the document prior to deletion + // e.g. {'name': 'Marie', 'age': 66} + const deletedValue = snap.data(); + + // perform desired operations ... + }); + // [END trigger_document_deleted] } function triggerDocumentAnyChange() { - // [START trigger_document_any_change] - exports.modifyUser = functions.firestore - .document('users/{userID}') - .onWrite((change, context) => { - // Get an object with the current document value. - // If the document does not exist, it has been deleted. - const document = change.after.exists ? change.after.data() : null; - - // Get an object with the previous document value (for update or delete) - const oldDocument = change.before.data(); - - // perform desired operations ... - }); - // [END trigger_document_any_change] + // [START trigger_document_any_change] + exports.modifyUser = functions.firestore + .document('users/{userID}') + .onWrite((change, context) => { + // Get an object with the current document value. + // If the document does not exist, it has been deleted. + const document = change.after.exists ? change.after.data() : null; + + // Get an object with the previous document value (for update or delete) + const oldDocument = change.before.data(); + + // perform desired operations ... + }); + // [END trigger_document_any_change] } function readingData() { - // [START reading_data] - exports.updateUser = functions.firestore - .document('users/{userId}') - .onUpdate((change, context) => { - // Get an object representing the current document - const newValue = change.after.data(); - - // ...or the previous value before this update - const previousValue = change.before.data(); - }); - // [END reading_data] + // [START reading_data] + exports.updateUser = functions.firestore + .document('users/{userId}') + .onUpdate((change, context) => { + // Get an object representing the current document + const newValue = change.after.data(); + + // ...or the previous value before this update + const previousValue = change.before.data(); + }); + // [END reading_data] } function readingDataWithGet(snap) { - // [START reading_data_with_get] - // Fetch data using standard accessors - const age = snap.data().age; - const name = snap.data()['name']; - - // Fetch data using built in accessor - const experience = snap.get('experience'); - // [END reading_data_with_get] + // [START reading_data_with_get] + // Fetch data using standard accessors + const age = snap.data().age; + const name = snap.data()['name']; + + // Fetch data using built in accessor + const experience = snap.get('experience'); + // [END reading_data_with_get] } function writingData() { - // [START writing_data] - // Listen for updates to any `user` document. - exports.countNameChanges = functions.firestore - .document('users/{userId}') - .onUpdate((change, context) => { - // Retrieve the current and previous value - const data = change.after.data(); - const previousData = change.before.data(); - - // We'll only update if the name has changed. - // This is crucial to prevent infinite loops. - if (data.name == previousData.name) return; - - // Retrieve the current count of name changes - let count = data.name_change_count; - if (!count) { - count = 0; - } - - // Then return a promise of a set operation to update the count - return change.after.ref.set({ - name_change_count: count + 1 - }, {merge: true}); - }); - // [END writing_data] + // [START writing_data] + // Listen for updates to any `user` document. + exports.countNameChanges = functions.firestore + .document('users/{userId}') + .onUpdate((change, context) => { + // Retrieve the current and previous value + const data = change.after.data(); + const previousData = change.before.data(); + + // We'll only update if the name has changed. + // This is crucial to prevent infinite loops. + if (data.name == previousData.name) return; + + // Retrieve the current count of name changes + let count = data.name_change_count; + if (!count) { + count = 0; + } + + // Then return a promise of a set operation to update the count + return change.after.ref.set({ + name_change_count: count + 1 + }, {merge: true}); + }); + // [END writing_data] } function basicWildcard() { - // [START basic_wildcard] - // Listen for changes in all documents and all sub-collections - exports.useWildcard = functions.firestore - .document('users/{userId}') - .onWrite((change, context) => { - // If we set `/users/marie` to {name: "marie"} then - // context.params.userId == "marie" - // ... and ... - // change.after.data() == {name: "Marie"} - }); - // [END basic_wildcard] + // [START basic_wildcard] + // Listen for changes in all documents and all sub-collections + exports.useWildcard = functions.firestore + .document('users/{userId}') + .onWrite((change, context) => { + // If we set `/users/marie` to {name: "marie"} then + // context.params.userId == "marie" + // ... and ... + // change.after.data() == {name: "Marie"} + }); + // [END basic_wildcard] } function multiWildcard() { - // [START multi_wildcard] - // Listen for changes in all documents and all subcollections - exports.useMultipleWildcards = functions.firestore - .document('users/{userId}/{messageCollectionId}/{messageId}') - .onWrite((change, context) => { - // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then - // context.params.userId == "marie"; - // context.params.messageCollectionId == "incoming_messages"; - // context.params.messageId == "134"; - // ... and ... - // change.after.data() == {body: "Hello"} - }); - // [END multi_wildcard] + // [START multi_wildcard] + // Listen for changes in all documents and all subcollections + exports.useMultipleWildcards = functions.firestore + .document('users/{userId}/{messageCollectionId}/{messageId}') + .onWrite((change, context) => { + // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then + // context.params.userId == "marie"; + // context.params.messageCollectionId == "incoming_messages"; + // context.params.messageId == "134"; + // ... and ... + // change.after.data() == {body: "Hello"} + }); + // [END multi_wildcard] } From fbd1bcb218f1620ac190d07923a0f0d1558a7f6b Mon Sep 17 00:00:00 2001 From: Nicolas Garnier Date: Fri, 6 Apr 2018 20:43:52 +0200 Subject: [PATCH 19/19] Removing indent rule See: https://github.com/google/eslint-config-google/blob/master/index.js#L208-L209 --- .eslintrc.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2c127aed..4e8cd21c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -11,10 +11,6 @@ "sourceType": "module" }, "rules": { - "indent": [ - "error", - 4 - ], "linebreak-style": [ "error", "unix" @@ -30,4 +26,4 @@ "no-console": 0, "no-unused-vars": 0 } -} \ No newline at end of file +}