Skip to content

Commit 3dab2da

Browse files
committed
Review updates
1 parent 7ea301a commit 3dab2da

File tree

4 files changed

+106
-63
lines changed

4 files changed

+106
-63
lines changed

firestore-send-email/functions/lib/index.js

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,8 @@ function validateFieldArray(field, array) {
4040
if (!Array.isArray(array)) {
4141
throw new Error(`Invalid field "${field}". Expected an array of strings.`);
4242
}
43-
for (let i = 0; i < array.length; i++) {
44-
if (typeof array[i] !== "string") {
45-
throw new Error(`Invalid field "${field}". Expected an array of strings.`);
46-
}
43+
if (array.find(item => typeof item !== 'string')) {
44+
throw new Error(`Invalid field "${field}". Expected an array of strings.`);
4745
}
4846
}
4947
function processCreate(snap) {
@@ -70,7 +68,6 @@ function preparePayload(payload) {
7068
let to = [];
7169
let cc = [];
7270
let bcc = [];
73-
let uids = [];
7471
if (payload.to) {
7572
validateFieldArray("to", payload.to);
7673
to = [...to, ...payload.to];
@@ -89,51 +86,70 @@ function preparePayload(payload) {
8986
payload.bcc = bcc;
9087
return payload;
9188
}
92-
if (payload.toUids && config_1.default.usersCollection) {
93-
validateFieldArray("toUids", payload.toUids);
94-
uids = [...uids, ...payload.toUids];
89+
if (!config_1.default.usersCollection) {
90+
throw new Error("Must specify a users collection to send using uids.");
9591
}
96-
else if (payload.toUids && !config_1.default.usersCollection) {
97-
throw new Error(`'toUids' were provided, but no User collection was provided.`);
92+
let uids = [];
93+
if (payload.toUids) {
94+
validateFieldArray("toUids", payload.toUids);
95+
uids = uids.concat(payload.toUids);
9896
}
99-
if (payload.ccUids && config_1.default.usersCollection) {
97+
if (payload.ccUids) {
10098
validateFieldArray("ccUids", payload.ccUids);
101-
uids = [...uids, ...payload.ccUids];
99+
uids = uids.concat(payload.ccUids);
102100
}
103-
else if (payload.ccUids && !config_1.default.usersCollection) {
104-
throw new Error(`'ccUids' were provided, but no User collection was provided.`);
105-
}
106-
if (payload.bccUids && config_1.default.usersCollection) {
101+
if (payload.bccUids) {
107102
validateFieldArray("bccUids", payload.bccUids);
108-
uids = [...uids, ...payload.bccUids];
103+
uids = uids.concat(payload.bccUids);
109104
}
110-
else if (payload.bccUids && !config_1.default.usersCollection) {
111-
throw new Error(`'bccUids' were provided, but no User collection was provided.`);
112-
}
113-
const documents = yield db.getAll(...uids.map((uid) => db.collection(config_1.default.usersCollection).doc(uid)), {
105+
const toFetch = {};
106+
uids.forEach(uid => toFetch[uid] = null);
107+
const documents = yield db.getAll(...Object.keys(toFetch).map((uid) => db.collection(config_1.default.usersCollection).doc(uid)), {
114108
fieldMask: ["email"],
115109
});
116-
const userMap = {};
110+
const missingUids = [];
117111
documents.forEach((documentSnapshot) => {
118112
if (documentSnapshot.exists) {
119113
const email = documentSnapshot.get("email");
120114
if (email) {
121-
userMap[documentSnapshot.id] = email;
115+
toFetch[documentSnapshot.id] = email;
116+
}
117+
else {
118+
missingUids.push(documentSnapshot.id);
122119
}
123120
}
121+
else {
122+
missingUids.push(documentSnapshot.id);
123+
}
124124
});
125+
logs.missingUids(missingUids);
125126
if (payload.toUids) {
126-
const toUidsEmails = payload.toUids.map((uid) => userMap[uid]);
127-
payload.to = [...to, ...toUidsEmails];
127+
payload.toUids.forEach((uid) => {
128+
const email = toFetch[uid];
129+
if (email) {
130+
to.push(email);
131+
}
132+
});
128133
}
134+
payload.to = to;
129135
if (payload.ccUids) {
130-
const ccUidsEmails = payload.ccUids.map((uid) => userMap[uid]);
131-
payload.cc = [...cc, ...ccUidsEmails];
136+
payload.ccUids.forEach((uid) => {
137+
const email = toFetch[uid];
138+
if (email) {
139+
cc.push(email);
140+
}
141+
});
132142
}
143+
payload.cc = cc;
133144
if (payload.bccUids) {
134-
const bccUidsEmails = payload.bccUids.map((uid) => userMap[uid]);
135-
payload.bcc = [...cc, ...bccUidsEmails];
145+
payload.bccUids.forEach((uid) => {
146+
const email = toFetch[uid];
147+
if (email) {
148+
bcc.push(email);
149+
}
150+
});
136151
}
152+
payload.bcc = bcc;
137153
return payload;
138154
});
139155
}

firestore-send-email/functions/lib/logs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ function missingDeliveryField(ref) {
5151
console.error(`message=${ref.path} is missing 'delivery' field`);
5252
}
5353
exports.missingDeliveryField = missingDeliveryField;
54+
function missingUids(uids) {
55+
console.log(`The following uids were provided, however a document does not exist or has no 'email' field: ${uids.join(',')}`);
56+
}
57+
exports.missingUids = missingUids;

firestore-send-email/functions/src/index.ts

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,10 @@ function validateFieldArray(field: string, array?: string[]) {
7171
throw new Error(`Invalid field "${field}". Expected an array of strings.`);
7272
}
7373

74-
for (let i = 0; i < array.length; i++) {
75-
if (typeof array[i] !== "string") {
76-
throw new Error(
77-
`Invalid field "${field}". Expected an array of strings.`
78-
);
79-
}
74+
if (array.find(item => typeof item !== 'string')) {
75+
throw new Error(
76+
`Invalid field "${field}". Expected an array of strings.`
77+
);
8078
}
8179
}
8280

@@ -108,7 +106,6 @@ async function preparePayload(payload: QueuePayload): Promise<QueuePayload> {
108106
let to: string[] = [];
109107
let cc: string[] = [];
110108
let bcc: string[] = [];
111-
let uids: string[] = [];
112109

113110
if (payload.to) {
114111
validateFieldArray("to", payload.to);
@@ -133,66 +130,88 @@ async function preparePayload(payload: QueuePayload): Promise<QueuePayload> {
133130
return payload;
134131
}
135132

136-
if (payload.toUids && config.usersCollection) {
133+
if (!config.usersCollection) {
134+
throw new Error("Must specify a users collection to send using uids.");
135+
}
136+
137+
let uids: string[] = [];
138+
139+
if (payload.toUids) {
137140
validateFieldArray("toUids", payload.toUids);
138-
uids = [...uids, ...payload.toUids];
139-
} else if (payload.toUids && !config.usersCollection) {
140-
throw new Error(
141-
`'toUids' were provided, but no User collection was provided.`
142-
);
141+
uids = uids.concat(payload.toUids);
143142
}
144143

145-
if (payload.ccUids && config.usersCollection) {
144+
if (payload.ccUids) {
146145
validateFieldArray("ccUids", payload.ccUids);
147-
uids = [...uids, ...payload.ccUids];
148-
} else if (payload.ccUids && !config.usersCollection) {
149-
throw new Error(
150-
`'ccUids' were provided, but no User collection was provided.`
151-
);
146+
uids = uids.concat(payload.ccUids);
152147
}
153148

154-
if (payload.bccUids && config.usersCollection) {
149+
if (payload.bccUids) {
155150
validateFieldArray("bccUids", payload.bccUids);
156-
uids = [...uids, ...payload.bccUids];
157-
} else if (payload.bccUids && !config.usersCollection) {
158-
throw new Error(
159-
`'bccUids' were provided, but no User collection was provided.`
160-
);
151+
uids = uids.concat(payload.bccUids);
161152
}
162153

154+
const toFetch = {};
155+
uids.forEach(uid => toFetch[uid] = null);
156+
163157
const documents = await db.getAll(
164-
...uids.map((uid) => db.collection(config.usersCollection).doc(uid)),
158+
...Object.keys(toFetch).map((uid) => db.collection(config.usersCollection).doc(uid)),
165159
{
166160
fieldMask: ["email"],
167161
}
168162
);
169163

170-
const userMap: { [key: string]: string } = {};
164+
const missingUids = [];
165+
171166
documents.forEach((documentSnapshot) => {
172167
if (documentSnapshot.exists) {
173168
const email = documentSnapshot.get("email");
174169

175170
if (email) {
176-
userMap[documentSnapshot.id] = email;
171+
toFetch[documentSnapshot.id] = email;
172+
} else {
173+
missingUids.push(documentSnapshot.id);
177174
}
175+
} else {
176+
missingUids.push(documentSnapshot.id);
178177
}
179178
});
180179

180+
logs.missingUids(missingUids);
181+
181182
if (payload.toUids) {
182-
const toUidsEmails: string[] = payload.toUids.map((uid) => userMap[uid]);
183-
payload.to = [...to, ...toUidsEmails];
183+
payload.toUids.forEach((uid) => {
184+
const email = toFetch[uid];
185+
if (email) {
186+
to.push(email);
187+
}
188+
});
184189
}
185190

191+
payload.to = to;
192+
186193
if (payload.ccUids) {
187-
const ccUidsEmails: string[] = payload.ccUids.map((uid) => userMap[uid]);
188-
payload.cc = [...cc, ...ccUidsEmails];
194+
payload.ccUids.forEach((uid) => {
195+
const email = toFetch[uid];
196+
if (email) {
197+
cc.push(email);
198+
}
199+
});
189200
}
190201

202+
payload.cc = cc;
203+
191204
if (payload.bccUids) {
192-
const bccUidsEmails: string[] = payload.bccUids.map((uid) => userMap[uid]);
193-
payload.bcc = [...cc, ...bccUidsEmails];
205+
payload.bccUids.forEach((uid) => {
206+
const email = toFetch[uid];
207+
if (email) {
208+
bcc.push(email);
209+
}
210+
});
194211
}
195212

213+
payload.bcc = bcc;
214+
196215
return payload;
197216
}
198217

firestore-send-email/functions/src/logs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ export function deliveryError(
6464
export function missingDeliveryField(ref: FirebaseFirestore.DocumentReference) {
6565
console.error(`message=${ref.path} is missing 'delivery' field`);
6666
}
67+
68+
export function missingUids(uids: string[]) {
69+
console.log(`The following uids were provided, however a document does not exist or has no 'email' field: ${uids.join(',')}`);
70+
}

0 commit comments

Comments
 (0)