Skip to content

Commit 750bb0f

Browse files
authored
Merge pull request #66 from firebase/next
November 7, 2019 Release
2 parents f01cf23 + 75cfd53 commit 750bb0f

File tree

148 files changed

+5531
-1808
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+5531
-1808
lines changed

.prettierignore

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package.json
22
extension.yaml
3-
webpack.config.js
3+
package-lock.json
4+
45
**/node_modules/**
56

67
# generated files
78
README.md
8-
POSTINSTALL.md
9-
PREINSTALL.md
109
**/functions/lib/**
1110
**/dist/**
11+
12+
# extension install md files
13+
# - excluded as prettier escapes variables e.g. `${PROJECT_ID}` becomes `\${PROJECT_ID}`
14+
POSTINSTALL.md
15+
PREINSTALL.md

.prettierrc.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
trailingComma: es5
1616
arrowParens: always
1717
overrides:
18-
- files: "*.yaml"
18+
- files: "*.{yml,yaml}"
1919
options:
2020
proseWrap: always

.travis.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
language: node_js
2+
3+
node_js:
4+
- 8
5+
- 10
6+
- 12
7+
8+
stages:
9+
- validate
10+
- test
11+
12+
jobs:
13+
include:
14+
- stage: validate
15+
name: "TypeScript Compile"
16+
script: npm run clean && npm run build
17+
- stage: validate
18+
name: "Prettier Format Check"
19+
script: npm run lint
20+
- stage: test
21+
script: npm run test-coverage

auth-mailchimp-sync/README.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
# auth-mailchimp-sync
1+
# Sync with Mailchimp
22

3-
**VERSION**: 0.1.0
3+
**Description**: Adds new users from Firebase Authentication to a specified Mailchimp audience.
44

5-
**DESCRIPTION**: Adds new users from Firebase Authentication to a specified Mailchimp audience.
65

76

7+
**Details**: Use this extension to add new users to an existing [Mailchimp](https://mailchimp.com) audience.
88

9-
**CONFIGURATION PARAMETERS:**
9+
This extension adds the email address of each new user to your specified Mailchimp audience. Also, if the user deletes their user account for your app, this extension removes the user from the Mailchimp audience.
1010

11-
* Deployment location: Where should the extension be deployed? For help selecting a location, refer to the [location selection guide](https://firebase.google.com/docs/functions/locations).
11+
**Note:** To use this extension, you need to manage your users with Firebase Authentication.
1212

13-
* Mailchimp API key: What is your Mailchimp API key? To obtain a Mailchimp API key, go to your [Mailchimp account](https://admin.mailchimp.com/account/api/).
13+
This extension uses Mailchimp, so you'll need to supply your Mailchimp API Key and Audience ID when installing this extension.
1414

15-
* Audience ID: What is the Mailchimp Audience ID to which you want to subscribe new users? To find your Audience ID: visit https://admin.mailchimp.com/lists, click on the desired audience or create a new audience, then select **Settings**. Look for **Audience ID** (for example, `27735fc60a`).
15+
#### Additional setup
1616

17-
* Contact status: When the extension adds a new user to the Mailchimp audience, what is their initial status? This value can be `subscribed` or `pending`. `subscribed` means the user can receive campaigns; `pending` means the user still needs to opt-in to receive campaigns.
17+
Make sure that you've set up [Firebase Authentication](https://firebase.google.com/docs/auth) to manage your users.
1818

19+
You must also have a Mailchimp account before installing this extension.
1920

21+
#### Billing
2022

21-
**CLOUD FUNCTIONS CREATED:**
23+
This extension uses other Firebase or Google Cloud Platform services which may have associated charges:
2224

23-
* addUserToList (providers/firebase.auth/eventTypes/user.create)
25+
- Firebase Realtime Database
26+
- Cloud Functions
2427

25-
* removeUserFromList (providers/firebase.auth/eventTypes/user.delete)
28+
When you use Firebase Extensions, you're only charged for the underlying resources that you use. A paid-tier billing plan is only required if the extension uses a service that requires a paid-tier plan, for example calling to a Google Cloud Platform API or making outbound network requests to non-Google services. All Firebase services offer a free tier of usage. [Learn more about Firebase billing.](https://firebase.google.com/pricing)
2629

30+
Usage of this extension also requires you to have a Mailchimp account. You are responsible for any associated costs with your usage of Mailchimp.
2731

2832

29-
**DETAILS**: Use this extension to add new users to an existing [Mailchimp](https://mailchimp.com) audience.
3033

31-
This extension adds the email address of each new user to your specified Mailchimp audience. Also, if the user deletes their user account for your app, this extension removes the user from the Mailchimp audience.
3234

33-
**Note:** To use this extension, you need to manage your users with Firebase Authentication.
3435

35-
This extension uses Mailchimp, so you'll need to supply your Mailchimp API Key and Audience ID when installing this extension.
36+
**Configuration Parameters:**
3637

37-
#### Additional setup
38+
* Deployment location: Where should the extension be deployed? For help selecting a location, refer to the [location selection guide](https://firebase.google.com/docs/functions/locations).
3839

39-
Make sure that you've set up [Firebase Authentication](https://firebase.google.com/docs/auth) to manage your users.
40+
* Mailchimp API key: What is your Mailchimp API key? To obtain a Mailchimp API key, go to your [Mailchimp account](https://admin.mailchimp.com/account/api/).
4041

41-
You must also have a Mailchimp account before installing this extension.
42+
* Audience ID: What is the Mailchimp Audience ID to which you want to subscribe new users? To find your Audience ID: visit https://admin.mailchimp.com/lists, click on the desired audience or create a new audience, then select **Settings**. Look for **Audience ID** (for example, `27735fc60a`).
4243

43-
#### Billing
44+
* Contact status: When the extension adds a new user to the Mailchimp audience, what is their initial status? This value can be `subscribed` or `pending`. `subscribed` means the user can receive campaigns; `pending` means the user still needs to opt-in to receive campaigns.
4445

45-
This extension uses other Firebase or Google Cloud Platform services which may have associated charges:
4646

47-
- Firebase Realtime Database
48-
- Cloud Functions
4947

50-
When you use Firebase Extensions, you're only charged for the underlying resources that you use. A paid-tier billing plan is only required if the extension uses a service that requires a paid-tier plan, for example calling to a Google Cloud Platform API or making outbound network requests to non-Google services. All Firebase services offer a free tier of usage. [Learn more about Firebase billing.](https://firebase.google.com/pricing)
48+
**Cloud Functions:**
5149

52-
Usage of this extension also requires you to have a Mailchimp account. You are responsible for any associated costs with your usage of Mailchimp.
50+
* **addUserToList:** Listens for new user accounts (as managed by Firebase Authentication), then automatically adds the new user to your specified MailChimp audience.
51+
52+
* **removeUserFromList:** Listens for existing user accounts to be deleted (as managed by Firebase Authentication), then automatically removes them from your specified MailChimp audience.

auth-mailchimp-sync/extension.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ description:
2323
license: Apache-2.0
2424
billingRequired: true
2525
sourceUrl: https://github.com/firebase/extensions/tree/master/auth-mailchimp-sync
26-
releaseNotesUrl: https://github.com/firebase/extensions/commits/master
26+
releaseNotesUrl: https://github.com/firebase/extensions/releases
2727

2828
author:
2929
authorName: Firebase

auth-mailchimp-sync/jest.config.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,5 @@ module.exports = {
66
rootDir: "./",
77
preset: "ts-jest",
88
globalSetup: "./jest.setup.js",
9-
globalTeardown: "./jest.teardown.js"
9+
globalTeardown: "./jest.teardown.js",
1010
};
11-
12-

auth-mailchimp-sync/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

auth-mailchimp-sync/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"name": "auth-mailchimp-sync",
3-
"version": "0.1.0",
43
"description": "Add new users to a Mailchimp list, and delete them from the list when they delete their account.",
54
"main": "functions/lib/index.js",
65
"scripts": {
@@ -19,5 +18,6 @@
1918
"devDependencies": {
2019
"rimraf": "^2.6.3",
2120
"typescript": "^3.2.4"
22-
}
21+
},
22+
"private": true
2323
}

auth-mailchimp-sync/tsconfig.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,5 @@
33
"compilerOptions": {
44
"outDir": "functions/lib"
55
},
6-
"include": [
7-
"functions/src"
8-
]
6+
"include": ["functions/src"]
97
}

delete-user-data/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Version 0.1.2
2+
3+
feature - Add a new param for recursively deleting subcollections in Cloud Firestore (issue #14).
4+
fixed - Fixed "cold start" errors experienced when the extension runs after a period of inactivity (issue #48).

delete-user-data/README.md

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
1-
# delete-user-data
1+
# Delete User Data
22

3-
**VERSION**: 0.1.1
3+
**Description**: Deletes data keyed on a userId from Cloud Firestore, Realtime Database, and/or Cloud Storage when a user deletes their account.
44

5-
**DESCRIPTION**: Deletes data keyed on a userId from Cloud Firestore, Realtime Database, and/or Cloud Storage when a user deletes their account.
65

76

8-
9-
**CONFIGURATION PARAMETERS:**
10-
11-
* Deployment location: Where should the extension be deployed? You usually want a location close to your database. For help selecting a location, refer to the [location selection guide](https://firebase.google.com/docs/functions/locations#selecting_regions_for_firestore_and_storage).
12-
13-
* Cloud Firestore paths: Which paths in your Cloud Firestore instance contain user data? Leave empty if you don't use Cloud Firestore.
14-
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`.
15-
For example, if you have the collections `users` and `admins`, and each collection has documents with User ID as document IDs, then you can enter `users/{UID},admins/{UID}`.
16-
17-
* Realtime Database paths: Which paths in your Realtime Database instance contain user data? Leave empty if you don't use Realtime Database.
18-
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`.
19-
For example: `users/{UID},admins/{UID}`.
20-
21-
* Cloud Storage paths: Where in Google Cloud Storage do you store user data? Leave empty if you don't use Cloud Storage.
22-
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`. You can use `{DEFAULT}` to represent your default bucket.
23-
For example, if you are using your default bucket, and the bucket has files with the naming scheme `{UID}-pic.png`, then you can enter `{DEFAULT}/{UID}-pic.png`. If you also have files in another bucket called `my-awesome-app-logs`, and that bucket has files with the naming scheme `{UID}-logs.txt`, then you can enter `{DEFAULT}/{UID}-pic.png,my-awesome-app-logs/{UID}-logs.txt`.
24-
25-
26-
27-
**CLOUD FUNCTIONS CREATED:**
28-
29-
* clearData (providers/firebase.auth/eventTypes/user.delete)
30-
31-
32-
33-
**DETAILS**: Use this extension to automatically delete a user's data if the user is deleted from your authenticated users.
7+
**Details**: Use this extension to automatically delete a user's data if the user is deleted from your authenticated users.
348

359
You can configure this extension to delete user data from any or all of the following: Cloud Firestore, Realtime Database, or Cloud Storage. Each trigger of the extension to delete data is keyed to the user's UserId.
3610

@@ -57,13 +31,40 @@ When you use Firebase Extensions, you're only charged for the underlying resourc
5731

5832

5933

60-
**ACCESS REQUIRED**:
34+
35+
**Configuration Parameters:**
36+
37+
* Deployment location: Where should the extension be deployed? You usually want a location close to your database. For help selecting a location, refer to the [location selection guide](https://firebase.google.com/docs/functions/locations).
38+
39+
* Cloud Firestore paths: Which paths in your Cloud Firestore instance contain user data? Leave empty if you don't use Cloud Firestore.
40+
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`.
41+
For example, if you have the collections `users` and `admins`, and each collection has documents with User ID as document IDs, then you can enter `users/{UID},admins/{UID}`.
42+
43+
* Cloud Firestore delete mode: (Only applicable if you use the `Cloud Firestore paths` parameter.) How do you want to delete Cloud Firestore documents? To also delete documents in subcollections, set this parameter to `recursive`.
44+
45+
* Realtime Database paths: Which paths in your Realtime Database instance contain user data? Leave empty if you don't use Realtime Database.
46+
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`.
47+
For example: `users/{UID},admins/{UID}`.
48+
49+
* Cloud Storage paths: Where in Google Cloud Storage do you store user data? Leave empty if you don't use Cloud Storage.
50+
Enter the full paths, separated by commas. You can represent the User ID of the deleted user with `{UID}`. You can use `{DEFAULT}` to represent your default bucket.
51+
For example, if you are using your default bucket, and the bucket has files with the naming scheme `{UID}-pic.png`, then you can enter `{DEFAULT}/{UID}-pic.png`. If you also have files in another bucket called `my-awesome-app-logs`, and that bucket has files with the naming scheme `{UID}-logs.txt`, then you can enter `{DEFAULT}/{UID}-pic.png,my-awesome-app-logs/{UID}-logs.txt`.
52+
53+
54+
55+
**Cloud Functions:**
56+
57+
* **clearData:** Listens for user accounts to be deleted from your project's authenticated users, then removes any associated user data (based on Firebase Authentication's User ID) from Realtime Database, Cloud Firestore, and/or Cloud Storage.
58+
59+
60+
61+
**Access Required**:
6162

6263

6364

6465
This extension will operate with the following project IAM roles:
6566

66-
* datastore.user (Reason: Allows the extension to delete (user) data from Cloud Firestore.)
67+
* datastore.owner (Reason: Allows the extension to delete (user) data from Cloud Firestore.)
6768

6869
* firebasedatabase.admin (Reason: Allows the extension to delete (user) data from Realtime Database.)
6970

delete-user-data/extension.yaml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
name: delete-user-data
1616
displayName: Delete User Data
1717
specVersion: v1beta
18-
version: 0.1.1
18+
version: 0.1.2
1919

2020
description:
2121
Deletes data keyed on a userId from Cloud Firestore, Realtime
@@ -24,7 +24,7 @@ description:
2424
license: Apache-2.0
2525
billingRequired: false
2626
sourceUrl: https://github.com/firebase/extensions/tree/master/delete-user-data
27-
releaseNotesUrl: https://github.com/firebase/extensions/commits/master
27+
releaseNotesUrl: https://github.com/firebase/extensions/releases
2828

2929
author:
3030
authorName: Firebase
@@ -36,9 +36,12 @@ contributors:
3636
- authorName: Chris Bianca
3737
email: chris@csfrequency.com
3838
url: https://github.com/chrisbianca
39+
- authorName: Elliot Hesp
40+
email: elliot@invertase.io
41+
url: https://github.com/ehesp
3942

4043
roles:
41-
- role: datastore.user
44+
- role: datastore.owner
4245
reason: Allows the extension to delete (user) data from Cloud Firestore.
4346
- role: firebasedatabase.admin
4447
reason: Allows the extension to delete (user) data from Realtime Database.
@@ -99,6 +102,21 @@ params:
99102
For example, if you have the collections `users` and `admins`, and each collection
100103
has documents with User ID as document IDs, then you can enter `users/{UID},admins/{UID}`.
101104
105+
- param: FIRESTORE_DELETE_MODE
106+
type: select
107+
label: Cloud Firestore delete mode
108+
description: >-
109+
(Only applicable if you use the `Cloud Firestore paths` parameter.) How do you want
110+
to delete Cloud Firestore documents? To also delete documents in subcollections,
111+
set this parameter to `recursive`.
112+
options:
113+
- label: Recursive
114+
value: recursive
115+
- label: Shallow
116+
value: shallow
117+
default: shallow
118+
required: true
119+
102120
- param: RTDB_PATHS
103121
type: string
104122
label: Realtime Database paths

delete-user-data/functions/lib/config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
*/
1717
Object.defineProperty(exports, "__esModule", { value: true });
1818
exports.default = {
19-
firestorePaths: process.env.FIRESTORE_PATHS,
2019
location: process.env.LOCATION,
20+
firestorePaths: process.env.FIRESTORE_PATHS,
21+
firestoreDeleteMode: process.env.FIRESTORE_DELETE_MODE,
2122
rtdbPaths: process.env.RTDB_PATHS,
2223
storagePaths: process.env.STORAGE_PATHS,
2324
};

delete-user-data/functions/lib/index.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
2525
Object.defineProperty(exports, "__esModule", { value: true });
2626
const admin = require("firebase-admin");
2727
const functions = require("firebase-functions");
28+
const firebase_tools = require("firebase-tools");
2829
const config_1 = require("./config");
2930
const logs = require("./logs");
3031
// Initialize the Firebase Admin SDK
@@ -113,12 +114,26 @@ const clearFirestoreData = (firestorePaths, uid) => __awaiter(this, void 0, void
113114
const paths = extractUserPaths(firestorePaths, uid);
114115
const promises = paths.map((path) => __awaiter(this, void 0, void 0, function* () {
115116
try {
116-
logs.firestorePathDeleting(path);
117-
yield admin
118-
.firestore()
119-
.doc(path)
120-
.delete();
121-
logs.firestorePathDeleted(path);
117+
const isRecursive = config_1.default.firestoreDeleteMode === 'recursive';
118+
if (!isRecursive) {
119+
const firestore = admin.firestore();
120+
logs.firestorePathDeleting(path, false);
121+
// Wrapping in transaction to allow for automatic retries (#48)
122+
yield firestore.runTransaction((transaction => {
123+
transaction.delete(firestore.doc(path));
124+
return Promise.resolve();
125+
}));
126+
logs.firestorePathDeleted(path, false);
127+
}
128+
else {
129+
logs.firestorePathDeleting(path, true);
130+
yield firebase_tools.firestore.delete(path, {
131+
project: process.env.PROJECT_ID,
132+
recursive: true,
133+
yes: true,
134+
});
135+
logs.firestorePathDeleted(path, true);
136+
}
122137
}
123138
catch (err) {
124139
logs.firestorePathError(path, err);

delete-user-data/functions/lib/logs.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ exports.firestoreDeleting = () => {
2828
exports.firestoreNotConfigured = () => {
2929
console.log("Cloud Firestore paths are not configured, skipping");
3030
};
31-
exports.firestorePathDeleted = (path) => {
32-
console.log(`Deleted: '${path}' from Cloud Firestore`);
31+
exports.firestorePathDeleted = (path, recursive) => {
32+
console.log(`Deleted: '${path}' from Cloud Firestore ${recursive ? 'with recursive delete' : ''}`);
3333
};
34-
exports.firestorePathDeleting = (path) => {
35-
console.log(`Deleting: '${path}' from Cloud Firestore`);
34+
exports.firestorePathDeleting = (path, recursive) => {
35+
console.log(`Deleting: '${path}' from Cloud Firestore ${recursive ? 'with recursive delete' : ''}`);
3636
};
3737
exports.firestorePathError = (path, err) => {
3838
console.error(`Error when deleting: '${path}' from Cloud Firestore`, err);

0 commit comments

Comments
 (0)