-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Add script to generate mock data for FriendlyEats quickstart
#728
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b796849
e302221
5e6531e
b0e0710
12f3083
8e2a55b
09c9e69
c959a35
e3ea6b3
a422b63
bb945e8
19248e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "parserOptions": { | ||
| "sourceType": "module" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| /** | ||
| * Copyright 2023 Google LLC | ||
| * | ||
| * 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. | ||
| */ | ||
|
|
||
|
|
||
| /** If connecting to a live Firebase project (one that you set up in the | ||
| * Firebase console) put your config vars into the `prod` field object here | ||
| * and change the `initializeApp` value in `app.module.ts` to `environment.prod`. | ||
| * Otherwise, leave untouched to enable connection to demo project and emulators. | ||
| */ | ||
|
|
||
| export const data = { | ||
| words: [ | ||
| 'Bar', | ||
| 'Fire', | ||
| 'Grill', | ||
| 'Drive Thru', | ||
| 'Place', | ||
| 'Best', | ||
| 'Spot', | ||
| 'Prime', | ||
| 'Eatin\'', | ||
| ], | ||
| cities: [ | ||
| 'Albuquerque', | ||
| 'Arlington', | ||
| 'Atlanta', | ||
| 'Austin', | ||
| 'Baltimore', | ||
| 'Boston', | ||
| 'Charlotte', | ||
| 'Chicago', | ||
| 'Cleveland', | ||
| 'Colorado Springs', | ||
| 'Columbus', | ||
| 'Dallas', | ||
| 'Denver', | ||
| 'Detroit', | ||
| 'El Paso', | ||
| 'Fort Worth', | ||
| 'Fresno', | ||
| 'Houston', | ||
| 'Indianapolis', | ||
| 'Jacksonville', | ||
| 'Kansas City', | ||
| 'Las Vegas', | ||
| 'Long Island', | ||
| 'Los Angeles', | ||
| 'Louisville', | ||
| 'Memphis', | ||
| 'Mesa', | ||
| 'Miami', | ||
| 'Milwaukee', | ||
| 'Nashville', | ||
| 'New York', | ||
| 'Oakland', | ||
| 'Oklahoma', | ||
| 'Omaha', | ||
| 'Philadelphia', | ||
| 'Phoenix', | ||
| 'Portland', | ||
| 'Raleigh', | ||
| 'Sacramento', | ||
| 'San Antonio', | ||
| 'San Diego', | ||
| 'San Francisco', | ||
| 'San Jose', | ||
| 'Tucson', | ||
| 'Tulsa', | ||
| 'Virginia Beach', | ||
| 'Washington', | ||
| ], | ||
| categories: [ | ||
| 'Brunch', | ||
| 'Burgers', | ||
| 'Coffee', | ||
| 'Deli', | ||
| 'Dim Sum', | ||
| 'Indian', | ||
| 'Italian', | ||
| 'Mediterranean', | ||
| 'Mexican', | ||
| 'Pizza', | ||
| 'Ramen', | ||
| 'Sushi', | ||
| ], | ||
| ratingsTexts: { | ||
| 1: 'Would never eat here again!', | ||
| 2: 'Not my cup of tea.', | ||
| 3: 'Exactly okay :/', | ||
| 4: 'Actually pretty good, would recommend!', | ||
| 5: 'This is my favorite place. Literally.', | ||
| }, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| /** | ||
| * Copyright 2023 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. | ||
| */ | ||
|
|
||
| /** | ||
| * This script creates a set of fake restaurants with fake reviews and | ||
| * populates the Firestore database with them. An `Anonymous` user is | ||
| * created for this (in `signInWithAnonCredentials`) since the rules | ||
| * defined in `../../firestore.rules` prevent unauthenticated users from | ||
| * modifying the contents of the firestore database. | ||
| */ | ||
|
|
||
| import { initializeApp } from 'firebase/app'; | ||
| import { | ||
| getFirestore, | ||
| connectFirestoreEmulator, | ||
| addDoc, | ||
| collection, | ||
| } from 'firebase/firestore/lite'; | ||
| import { | ||
| getAuth, | ||
| connectAuthEmulator, | ||
| createUserWithEmailAndPassword, | ||
| signInWithEmailAndPassword, | ||
| } from 'firebase/auth'; | ||
|
|
||
| import { projectConfig } from './environment.js'; | ||
| import { data } from './MockRestaurantData.js'; | ||
|
|
||
| const app = initializeApp(projectConfig); | ||
| const auth = getAuth(app); | ||
| const db = getFirestore(app); | ||
|
|
||
| /** | ||
| * Connect to emulators if a `demo` configuration hasn been pulled from | ||
| * environment.js. | ||
| */ | ||
| if (app.options.projectId.indexOf('demo-') == 0) { | ||
| connectFirestoreEmulator(db, '127.0.0.1', 8080); | ||
| connectAuthEmulator(auth, 'http://127.0.0.1:9099'); | ||
| } | ||
|
|
||
| /** | ||
| * Signs into an `Anonymous` user with which to post restaurants and comments. | ||
| */ | ||
| const signInWithAnonCredentials = async () => { | ||
| try { | ||
| await signInWithEmailAndPassword( | ||
| auth, | ||
| '[email protected]', | ||
| 'AnonymousPassword' | ||
| ); | ||
| } catch (userNotCreatedError) { | ||
| await createUserWithEmailAndPassword( | ||
| auth, | ||
| '[email protected]', | ||
| 'AnonymousPassword' | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Adds a single mock restaurant, and an associated rating, to the Firestore | ||
| * database. | ||
| */ | ||
| const addFakeRestaurant = async (restaurant) => { | ||
| const restaurantRef = await addDoc(collection(db, 'restaurants'), restaurant); | ||
| addMockRating(restaurantRef.id, restaurant.avgRating); | ||
| }; | ||
|
|
||
| /** | ||
| * A function to generate 20 random `Restaurant` objects. The definiton | ||
| * for a `Restaurant` is given in `../types/restaurant.ts`. | ||
| * @returns A list of 20 mock `Restaurant` objects to send to firestore | ||
| */ | ||
| const generateMockRestaurants = () => { | ||
| var restaurants = []; | ||
|
|
||
| for (var i = 0; i < 20; i++) { | ||
| var name = getRandomItem(data.words) + ' ' + getRandomItem(data.words); | ||
| var category = getRandomItem(data.categories); | ||
| var city = getRandomItem(data.cities); | ||
| var price = Math.floor(Math.random() * 4) + 1; | ||
| var photoID = Math.floor(Math.random() * 22) + 1; | ||
| // TODO(abradham): Modify to be able to use local emulated storage bucket | ||
| var photo = | ||
| 'https://storage.googleapis.com/firestorequickstarts.appspot.com/food_' + | ||
| photoID + | ||
| '.png'; | ||
| var numRatings = 0; | ||
| var avgRating = Math.floor(Math.random() * 5) + 1; | ||
|
|
||
| restaurants.push({ | ||
| name: name, | ||
| category: category, | ||
| price: price, | ||
| city: city, | ||
| numRatings: numRatings, | ||
| avgRating: avgRating, | ||
| photo: photo, | ||
| }); | ||
| } | ||
|
|
||
| return restaurants; | ||
| }; | ||
|
|
||
| /** | ||
| * Adds a list of generated restaurants to Firestore database. | ||
| * @param {Restaurant[]} restaurntsArr | ||
| * @returns {Promise[]} List of promises | ||
| */ | ||
| const addMockRestaurants = async (restaurntsArr) => { | ||
| let promises = []; | ||
| for (var i = 0; i < restaurntsArr.length; i++) { | ||
| let promise = addFakeRestaurant(restaurntsArr[i]); | ||
| if (!promise) { | ||
| console.debug('Couldn\'t add a restaurant to firestore'); | ||
| return Promise.reject(); | ||
| } else { | ||
| promises.push(promise); | ||
| } | ||
| } | ||
|
|
||
| await Promise.all(promises); | ||
| }; | ||
|
|
||
| const getRandomItem = (arr) => { | ||
| return arr[Math.floor(Math.random() * arr.length)]; | ||
| }; | ||
|
|
||
| /** | ||
| * | ||
| * @param {string} restaurantId: Firebase document id of relevant restaurant object | ||
| * @param {number} avgRating: # of stars given to the restaurant | ||
| */ | ||
| const addMockRating = async (restaurantId, avgRating) => { | ||
| // Create new `rating` obj | ||
| const newRating = { | ||
| rating: avgRating, | ||
| text: data.ratingsTexts[avgRating], | ||
| userName: 'Anonymous (Bot)', | ||
| }; | ||
|
|
||
| // Add new rating to given restaurant's `ratings/` subcollection | ||
| await addDoc( | ||
| collection(db, `restaurants/${restaurantId}/ratings`), | ||
| newRating | ||
| ); | ||
| }; | ||
|
|
||
| const main = async () => { | ||
| // Connect to emulators if a `demo` environment is pulled | ||
| if (app.options.projectId.indexOf('demo-') == 0) { | ||
| connectFirestoreEmulator(db, '127.0.0.1', 8080); | ||
| connectAuthEmulator(auth, 'http://127.0.0.1:9099'); | ||
| } | ||
|
|
||
| await signInWithAnonCredentials(); | ||
| await addMockRestaurants(generateMockRestaurants()); | ||
| }; | ||
|
|
||
| main(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "name": "scripts", | ||
| "version": "1.0.0", | ||
| "description": "A script to send mock data to the prod firebase console", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need this package.json anymore?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so; I'm importing node modules using the |
||
| "main": "PopulateFirestore.js", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "author": "", | ||
| "license": "Apache-2.0", | ||
| "type": "module" | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: let's note that this requires your configuration to exist in the config file