@edgedev/firebase 1.8.10 → 1.8.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -62
- package/edgeFirebase.ts +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
# @edgedev/firebase
|
|
2
2
|
|
|
3
|
-
A Vue 3 / Nuxt 3 Plugin or Nuxt 3 global composable for
|
|
3
|
+
A Vue 3 / Nuxt 3 Plugin or Nuxt 3 global composable for Firebase authentication and Firestore.
|
|
4
4
|
|
|
5
5
|
### Table of Contents
|
|
6
6
|
**[Installation](#installation)**
|
|
7
7
|
**[User Management and Collection Permissions](#user-management-and-collection-permissions)**
|
|
8
8
|
**[Firebase Authentication](#firebase-authentication)**
|
|
9
|
-
**[Firestore Basic Document Interactions](#firestore-
|
|
9
|
+
**[Firestore Basic Document Interactions](#firestore-basic-document-interactions)**
|
|
10
10
|
**[Firestore Snapshot Listeners](#firestore-snapshot-listeners)**
|
|
11
11
|
**[Firestore Static Collection Data](#firestore-static-collection-data)**
|
|
12
12
|
**[Run a Cloud Function](#run-a-cloud-function)**
|
|
13
13
|
**[Await and response](#responses)**
|
|
14
14
|
**[Firestore Rules](#firestore-rules)**
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
16
|
Before diving into the documentation, it's important to note that when using this package, you should always use `await` or wait for promises to resolve. This ensures that the Rule Helpers work correctly and provides the necessary information for verifying user access rights. Failing to wait for promises may lead to inconsistencies in access control and unexpected behavior in your application. For more information about how this class handles user permissions, please refer to the section below: **Rule Helpers: Managing User Permissions in Firestore**.
|
|
19
17
|
|
|
20
18
|
# Installation
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
Install using pnpm:
|
|
23
21
|
|
|
24
22
|
```bash
|
|
25
23
|
pnpm install @edgedev/firebase
|
|
26
24
|
```
|
|
25
|
+
|
|
27
26
|
### Installing with Nuxt 3 global composables
|
|
28
27
|
|
|
29
|
-
Add a file (whatever.ts) to your "composables" folder with this code:
|
|
28
|
+
Add a file (e.g., whatever.ts) to your "composables" folder with this code:
|
|
30
29
|
|
|
31
30
|
```typescript
|
|
32
31
|
import { EdgeFirebase } from "@edgedev/firebase";
|
|
@@ -37,9 +36,9 @@ const config = {
|
|
|
37
36
|
storageBucket: "your-storageBucket",
|
|
38
37
|
messagingSenderId: "your-messagingSenderId",
|
|
39
38
|
appId: "your-appId",
|
|
40
|
-
emulatorAuth: "", //
|
|
41
|
-
emulatorFirestore: "", //
|
|
42
|
-
emulatorFunctions: "", //
|
|
39
|
+
emulatorAuth: "", // Local emulator port for auth emulator
|
|
40
|
+
emulatorFirestore: "", // Local emulator port for Firestore emulator
|
|
41
|
+
emulatorFunctions: "", // Local emulator port for functions emulator, used to test Cloud Functions locally.
|
|
43
42
|
};
|
|
44
43
|
const isPersistant = true // If "persistence" is true, login will be saved locally, they can close their browser and when they open they will be logged in automatically. If "persistence" is false login saved only for the session.
|
|
45
44
|
const edgeFirebase = new EdgeFirebase(config, isPersistant);
|
|
@@ -54,13 +53,14 @@ export default defineNuxtConfig({ ssr: false });
|
|
|
54
53
|
### Installing as a plugin
|
|
55
54
|
|
|
56
55
|
#### Vue 3 plugin, main.js example:
|
|
56
|
+
|
|
57
57
|
```javascript
|
|
58
58
|
import { createApp } from "vue";
|
|
59
59
|
import App from "./App.vue";
|
|
60
60
|
|
|
61
|
-
//
|
|
61
|
+
// EdgeFirebase Plugin
|
|
62
62
|
import eFb from "@edgedev/firebase";
|
|
63
|
-
const isPersistant = true // If "persistence" is true, login will be saved locally, they can close their browser and when they open they will be logged in automatically. If "persistence" is false login saved only for the session.
|
|
63
|
+
const isPersistant = true // If "persistence" is true, login will be saved locally, they can close their browser and when they open they will be logged in automatically. If "persistence" is false, login saved only for the session.
|
|
64
64
|
app.use(eFb, {
|
|
65
65
|
apiKey: "your-apiKey",
|
|
66
66
|
authDomain: "your-authDomain",
|
|
@@ -68,22 +68,23 @@ app.use(eFb, {
|
|
|
68
68
|
storageBucket: "your-storageBucket",
|
|
69
69
|
messagingSenderId: "your-messagingSenderId",
|
|
70
70
|
appId: "your-appId",
|
|
71
|
-
emulatorAuth: "", //
|
|
72
|
-
emulatorFirestore: "", //
|
|
73
|
-
emulatorFunctions: "", //
|
|
71
|
+
emulatorAuth: "", // Local emulator port for auth emulator
|
|
72
|
+
emulatorFirestore: "", // Local emulator port for Firestore emulator
|
|
73
|
+
emulatorFunctions: "", // Local emulator port for functions emulator, used to test Cloud Functions locally.
|
|
74
74
|
}, isPersistant)
|
|
75
|
-
//
|
|
75
|
+
// End edgeFirebase
|
|
76
76
|
|
|
77
77
|
app.mount("#app");
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
#### Nuxt 3 example using the plugins folder:
|
|
81
|
-
Add a file (whatever.client.ts) to your "plugins" folder with the following code:
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
Add a file (e.g., whatever.client.ts) to your "plugins" folder with the following code:
|
|
83
|
+
|
|
84
|
+
***- Note the ".client" in the file name. If the file doesn't have that in the name, you must disable SSR in the Nuxt config.***
|
|
84
85
|
```javascript
|
|
85
86
|
import eFb from "@edgedev/firebase";
|
|
86
|
-
const isPersistant = true // If "persistence" is true, login will be saved locally, they can close their browser and when they open they will be logged in automatically. If "persistence" is false login saved only for the session.
|
|
87
|
+
const isPersistant = true // If "persistence" is true, login will be saved locally, they can close their browser and when they open they will be logged in automatically. If "persistence" is false, login saved only for the session.
|
|
87
88
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
88
89
|
nuxtApp.vueApp.use(eFb, {
|
|
89
90
|
apiKey: "your-apiKey",
|
|
@@ -92,19 +93,18 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
92
93
|
storageBucket: "your-storageBucket",
|
|
93
94
|
messagingSenderId: "your-messagingSenderId",
|
|
94
95
|
appId: "your-appId",
|
|
95
|
-
emulatorAuth: "", //
|
|
96
|
-
emulatorFirestore: "", //
|
|
96
|
+
emulatorAuth: "", // Local emulator port for auth emulator
|
|
97
|
+
emulatorFirestore: "", // Local emulator port for Firestore emulator
|
|
97
98
|
}, isPersistant);
|
|
98
99
|
});
|
|
99
100
|
```
|
|
100
|
-
***-Alternatively you can disable SSR for your entire Nuxt project instead of naming the plugin with ".client", update the nuxt.config.ts file:***
|
|
101
|
+
***- Alternatively, you can disable SSR for your entire Nuxt project instead of naming the plugin with ".client", update the nuxt.config.ts file:***
|
|
101
102
|
|
|
102
103
|
```javascript
|
|
103
104
|
export default defineNuxtConfig({ ssr: false });
|
|
104
105
|
```
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
#### After installing as a plugin you will need to include this in "script setup" in any component you want to use EdgeFirebase in:
|
|
107
|
+
#### After installing as a plugin, include this in "script setup" in any component you want to use EdgeFirebase in:
|
|
108
108
|
```javascript
|
|
109
109
|
<script setup>
|
|
110
110
|
import { inject } from "vue";
|
|
@@ -114,13 +114,13 @@ const edgeFirebase = inject("edgeFirebase");
|
|
|
114
114
|
|
|
115
115
|
### Firebase Trigger functions.
|
|
116
116
|
|
|
117
|
-
These
|
|
117
|
+
These functions react to updates in the `staged-users` Firestore collection. This trigger is designed to help maintain data consistency between the `staged-users` and `users` collections. When a document in the `staged-users` collection is updated, the trigger performs checks and updates the corresponding user data in the `users` collection, ensuring that both collections stay in sync.
|
|
118
118
|
|
|
119
119
|
The trigger considers various scenarios such as the presence of a `userId` field, differences between the old and new `templateUserId` fields, and event processing status. It uses helper functions like `setUser`, `shouldProcess`, and `markProcessed` to manage these scenarios and make the necessary updates to the `users` collection. These functions handle tasks like updating or creating user documents, checking if an event should be processed, and marking an event as processed.
|
|
120
120
|
|
|
121
121
|
In essence, the `updateUser` trigger streamlines user data management by automatically synchronizing updates between the `staged-users` and `users` collections in your Firebase project and adds another layer of security.
|
|
122
122
|
|
|
123
|
-
User
|
|
123
|
+
User management requires setting up a Firestore trigger function and helper functions in your Firebase functions. These functions are automatically added to functions/index.js in your project, wrapped in "// START @edge/firebase functions" and "// END @edge/firebase functions".
|
|
124
124
|
|
|
125
125
|
```javascript
|
|
126
126
|
const functions = require('firebase-functions')
|
|
@@ -133,19 +133,19 @@ const db = admin.firestore()
|
|
|
133
133
|
// END @edge/firebase functions
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
### To make sure your project is secure, install the
|
|
136
|
+
### To make sure your project is secure, install the Firestore rules document provided at the end of this documentation.
|
|
137
137
|
|
|
138
138
|
# User Management and Collection Permissions
|
|
139
139
|
|
|
140
140
|
### Adding a User
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
Before registering with a login and password, users or "Template Users" must be added (the first project user needs to be added manually, see the section below "Root permissions and first user"). When adding a user, you can pass role and/or special permissions and user meta data. For more explanations on role and special permissions, see below.
|
|
143
143
|
|
|
144
|
-
Adding a user creates a document for them in the collection "staged-users". The docId of this
|
|
144
|
+
Adding a user creates a document for them in the collection "staged-users". The docId of this document is used as a registration code and must be passed when using "registerUser" with the "registrationCode" variable.
|
|
145
145
|
|
|
146
|
-
The collection "staged-users" is a staging zone for all modifications and
|
|
146
|
+
The collection "staged-users" is a staging zone for all modifications and serves to sanitize the actual users in the "users" collection. Once a user is registered, their staged-user is linked to their "users" user. Generally speaking, the users in the "users" collection should not be modified. In fact, if you adopt the firestore rules shown in this document, direct modification of users in the "users" collection is not allowed. All user-related functions in this package (editing of meta, setting rules and special permissions, listing of users) are done on the "staged-users" collection.
|
|
147
147
|
|
|
148
|
-
To bypass adding users and allow "self
|
|
148
|
+
To bypass adding users and allow "self-registration", you can add a user that is a "Template User" by setting the field "isTemplate" = true. For a template user, you can also set up dynamic document generation and assign the registered user to that document with a specified role by setting "subCreate". Then, when registering the user, you can pass a "dynamicDocumentFieldValue" variable. In the example below, if on registration you passed: dynamicDocumentFieldValue = "My New Organization", a document would be created under myItems that would look like this: {name: "My New Organization"}. The user would also be assigned as an admin to that newly created document. If your project is going to be completely self-registration, you can create a "Template User" and hard-code that registration id into your registration process.
|
|
149
149
|
|
|
150
150
|
How to add a user:
|
|
151
151
|
|
|
@@ -193,11 +193,9 @@ interface newUser {
|
|
|
193
193
|
}
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
196
|
### Register User
|
|
199
197
|
|
|
200
|
-
After
|
|
198
|
+
After someone has been added as a user, they will need to "self-register" to begin using the system. Only users that have been added already by someone with assign permissions can register. The function also checks to make sure they aren't already registered.
|
|
201
199
|
|
|
202
200
|
```javascript
|
|
203
201
|
edgeFirebase.registerUser({
|
|
@@ -206,8 +204,8 @@ After someoene has been added as a user they will need to "self register" to beg
|
|
|
206
204
|
meta: {
|
|
207
205
|
firstName: "John",
|
|
208
206
|
lastName: "Doe"
|
|
209
|
-
} // This is just an example of meta, it can contain any fields and any number of fields.
|
|
210
|
-
registrationCode: (document id) // This is the document id of either an added user or a template user, when using a template you can simply hardcode the registrationCode of the remplate to allow self registration.
|
|
207
|
+
}, // This is just an example of meta, it can contain any fields and any number of fields.
|
|
208
|
+
registrationCode: (document id), // This is the document id of either an added user or a template user, when using a template you can simply hardcode the registrationCode of the remplate to allow self registration.
|
|
211
209
|
dynamicDocumentFieldValue: "" // Optional - See explaintion above about self registration and dynamic collectionPath for user roles.
|
|
212
210
|
});
|
|
213
211
|
```
|
|
@@ -232,8 +230,8 @@ Calling this will generate a Microsoft Sign In Popup and register the user using
|
|
|
232
230
|
meta: {
|
|
233
231
|
firstName: "John",
|
|
234
232
|
lastName: "Doe"
|
|
235
|
-
} // This is just an example of meta, it can contain any fields and any number of fields.
|
|
236
|
-
registrationCode: (document id) // This is the document id of either an added user or a template user, when using a template you can simply hardcode the registrationCode of the remplate to allow self registration.
|
|
233
|
+
}, // This is just an example of meta, it can contain any fields and any number of fields.
|
|
234
|
+
registrationCode: (document id), // This is the document id of either an added user or a template user, when using a template you can simply hardcode the registrationCode of the remplate to allow self registration.
|
|
237
235
|
dynamicDocumentFieldValue: "" // Optional - See explaintion above about self registration and dynamic collectionPath for user roles.
|
|
238
236
|
},
|
|
239
237
|
'microsoft', // This is the authProvider only 'email' or 'microsoft' are supported, default is 'email',
|
|
@@ -241,8 +239,6 @@ Calling this will generate a Microsoft Sign In Popup and register the user using
|
|
|
241
239
|
);
|
|
242
240
|
```
|
|
243
241
|
|
|
244
|
-
|
|
245
|
-
|
|
246
242
|
### Explanation of permissions
|
|
247
243
|
|
|
248
244
|
- **assign: boolean** - When a user has this permission for a collection they can assign other users to the collection and change permissions for that collection. For a user to be able run setUser, storeCollectionPermisions, storeUserRoles, removeUserRoles, storeUserSpecialPermissions, or removeUserSpecialPermissions, they must have assign access to any of the collection paths passed into those functions.
|
|
@@ -252,7 +248,7 @@ Calling this will generate a Microsoft Sign In Popup and register the user using
|
|
|
252
248
|
|
|
253
249
|
### Collection permissions by role
|
|
254
250
|
|
|
255
|
-
Roles define what permissions the user
|
|
251
|
+
Roles define what permissions the user will have. The system will use collection-data/-default- to lookup the permissions for an assigned role. The default permissions can be changed or you can define role permissions based on specific collection paths. If a specific collection path is not found when looking up a user's role permissions
|
|
256
252
|
|
|
257
253
|
- **admin:** assign: true, write: true, read: true, delete: true
|
|
258
254
|
- **editor**: assign: false, write: true, read: true, delete: true
|
|
@@ -281,11 +277,9 @@ Deleting collection permissions. This is done to "clean up" whenever a collectio
|
|
|
281
277
|
"myItems/subitems/things")
|
|
282
278
|
```
|
|
283
279
|
|
|
284
|
-
|
|
285
|
-
|
|
286
280
|
### User roles for collections
|
|
287
281
|
|
|
288
|
-
Users are assigned roles based on collection paths.
|
|
282
|
+
Users are assigned roles based on collection paths. A role assigned by a collection path that has sub collections will also determine what the user can do on all sub collections or a user can be assigned a role specifically for a sub collection only. For example, if a user is assigned as an admin for "myItems/subitems/things" they will only have admin access to that collection. But if the user is assigned as an admin for "myItems" they will have the admin permissions for "myItems" and all sub collections of "myItems".
|
|
289
283
|
|
|
290
284
|
How to assign a user a role for a collection:
|
|
291
285
|
|
|
@@ -308,7 +302,7 @@ Remove a role from a user for a collection:
|
|
|
308
302
|
|
|
309
303
|
### Root permissions and first user
|
|
310
304
|
|
|
311
|
-
You can assign a user access to all collections in the entire project by giving them a role on "-", which is used to define the root collection path.
|
|
305
|
+
You can assign a user access to all collections in the entire project by giving them a role on "-", which is used to define the root collection path. This would be for someone who is acting like a super admin. If this is your first user, you will need to manually set them up in the Firstore console inside the "staged-users". Once a root user is added manually, you will need to "Register" that user using the docId of the "staged user" as the registration code, please see the user registration section of this documentation. You can use this user to add other "root users" or set up other collections and assign roles to them. You will also need to manually create the collection-data/-default- role permissions document (mentioned above) and the root permission document, see examples below:
|
|
312
306
|
|
|
313
307
|

|
|
314
308
|
|
|
@@ -318,7 +312,7 @@ You can assign a user access to all collections in the entire project by giving
|
|
|
318
312
|
|
|
319
313
|
### User special permissions
|
|
320
314
|
|
|
321
|
-
If you want to give a user a unique set of permissions for a collection that doesn't match the admin or user roles for that collection you can set "special permissions".
|
|
315
|
+
If you want to give a user a unique set of permissions for a collection that doesn't match the admin or user roles for that collection, you can set "special permissions".
|
|
322
316
|
|
|
323
317
|
```javascript
|
|
324
318
|
edgeFirebase.storeUserSpecialPermissions(
|
|
@@ -358,8 +352,6 @@ The remove user function doesn't actually delete the user completely from the sy
|
|
|
358
352
|
edgeFirebase.removeUser(docId);
|
|
359
353
|
```
|
|
360
354
|
|
|
361
|
-
|
|
362
|
-
|
|
363
355
|
### Delete Self
|
|
364
356
|
|
|
365
357
|
This function allows a user to delete their own account. It removes the user's document from both the `users` and `staged-users` collections in the database and also deletes the user's authentication record. The function returns an `actionResponse` object indicating the success or failure of the operation.
|
|
@@ -378,8 +370,6 @@ if (response.success) {
|
|
|
378
370
|
}
|
|
379
371
|
```
|
|
380
372
|
|
|
381
|
-
|
|
382
|
-
|
|
383
373
|
### Users Snapshot Data
|
|
384
374
|
|
|
385
375
|
This will create a reactive object (state.users) that contains the members of the collection passed to the snapshot if the user running the function has assign access for, it will be a listed index by docId.
|
|
@@ -477,6 +467,7 @@ A Promise that resolves when the sign-in process is complete. The Promise resolv
|
|
|
477
467
|
#### After Login, User information is contained in: edgeFirebase.user
|
|
478
468
|
|
|
479
469
|
The user object is reactive and contains these items:
|
|
470
|
+
|
|
480
471
|
```typescript
|
|
481
472
|
interface UserDataObject {
|
|
482
473
|
uid: string | null;
|
|
@@ -516,6 +507,7 @@ If there is an error logging in, **edgeFirebase.user.logInError** will be true a
|
|
|
516
507
|
After logging in, **edgeFirebase.logOut** becomes available. Logging out will also automatically disconnect all FireStore listeners.
|
|
517
508
|
|
|
518
509
|
Here is a sample component using the login:
|
|
510
|
+
|
|
519
511
|
```html
|
|
520
512
|
<template>
|
|
521
513
|
<div>
|
|
@@ -550,6 +542,47 @@ const login = () => {
|
|
|
550
542
|
};
|
|
551
543
|
</script>
|
|
552
544
|
```
|
|
545
|
+
### Updating User Email
|
|
546
|
+
|
|
547
|
+
To update the email address of the current authenticated user, use the `edgeFirebase.updateEmail(newEmail)` method.
|
|
548
|
+
|
|
549
|
+
```javascript
|
|
550
|
+
const response = await edgeFirebase.updateEmail("new.email@example.com");
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
#### Parameters
|
|
554
|
+
|
|
555
|
+
- `newEmail` (string): The new email address to set for the user.
|
|
556
|
+
|
|
557
|
+
#### Returns
|
|
558
|
+
|
|
559
|
+
The method returns a Promise that resolves to an `actionResponse` object:
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
interface actionResponse {
|
|
563
|
+
success: boolean;
|
|
564
|
+
message: string;
|
|
565
|
+
meta: {};
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Example usage:
|
|
570
|
+
|
|
571
|
+
```javascript
|
|
572
|
+
<script setup>
|
|
573
|
+
async function changeEmail() {
|
|
574
|
+
const newEmail = "new.email@example.com";
|
|
575
|
+
const response = await edgeFirebase.updateEmail(newEmail);
|
|
576
|
+
if (response.success) {
|
|
577
|
+
console.log("Email updated successfully");
|
|
578
|
+
} else {
|
|
579
|
+
console.error("Error updating email:", response.message);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
</script>
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
|
|
553
586
|
### Change password:
|
|
554
587
|
|
|
555
588
|
This function allows a user to change their current password while logged in:
|
|
@@ -568,7 +601,7 @@ Step 1:
|
|
|
568
601
|
edgeFirebase.sendPasswordReset('user@edgemarketingdesign.com');
|
|
569
602
|
```
|
|
570
603
|
|
|
571
|
-
Step 2: (If the password redirect is setup to go a custom page, you'll need to pull the "oobCode" from the query string and pass that along with the
|
|
604
|
+
Step 2: (If the password redirect is setup to go a custom page, you'll need to pull the "oobCode" from the query string and pass that along with the new password.)
|
|
572
605
|
|
|
573
606
|
```javascript
|
|
574
607
|
edgeFirebase.passwordReset('NewPassword123','AAaaAABaaaaAAABBBaaaBBBBAaaaaBABAbbaa');
|
|
@@ -576,7 +609,7 @@ edgeFirebase.passwordReset('NewPassword123','AAaaAABaaaaAAABBBaaaBBBBAaaaaBABAbb
|
|
|
576
609
|
|
|
577
610
|
### Update User Meta:
|
|
578
611
|
|
|
579
|
-
A user can update their own meta data when logged in. The object
|
|
612
|
+
A user can update their own meta data when logged in. The object containing meta data will only update/add the keys passed in the object.
|
|
580
613
|
|
|
581
614
|
```javascript
|
|
582
615
|
edgeFirebase.setUserMeta({ lastName: "Smith" });
|
|
@@ -584,8 +617,8 @@ edgeFirebase.setUserMeta({ lastName: "Smith" });
|
|
|
584
617
|
|
|
585
618
|
# Firestore Basic Document Interactions
|
|
586
619
|
|
|
587
|
-
### Adding/
|
|
588
|
-
Both adding and updating a document use the same function:
|
|
620
|
+
### Adding/Updating a Document
|
|
621
|
+
Both adding and updating a document use the same function: **edgeFirebase.storeDoc(collectionPath, object)**. For a document to be updated, the object must contain the key **docId**, and the value must match the ID of a document in the collection being updated *(Note: All documents returned by edgeFirebase functions will already have docId inserted in the document objects)*. If the object does not contain docId or the docId doesn't match a document in the collection, a new document will be created.
|
|
589
622
|
|
|
590
623
|
```javascript
|
|
591
624
|
<script setup>
|
|
@@ -593,11 +626,12 @@ const addItem = {title: "Cool Thing"};
|
|
|
593
626
|
edgeFirebase.storeDoc("myItems", addItem);
|
|
594
627
|
</script>
|
|
595
628
|
```
|
|
596
|
-
|
|
629
|
+
|
|
630
|
+
Note: When a document is written to the collection, several other keys are added that can be referenced: **doc_created_at** (timestamp of doc creation), **last_updated** (timestamp document last written), **uid** (the user id of the user that updated or created the document).
|
|
597
631
|
|
|
598
632
|
### Updating a Document Field(s)
|
|
599
633
|
|
|
600
|
-
In contrast to the `storeDoc` method which adds or updates an entire document, you can use `edgeFirebase.changeDoc(collectionPath, docId, object)` to update individual fields in a document. This method allows you to specify the collection path, document ID, and the fields to update in the form of an object. It will only update the fields provided in the object while keeping the existing data in the document intact.
|
|
634
|
+
In contrast to the `storeDoc` method, which adds or updates an entire document, you can use `edgeFirebase.changeDoc(collectionPath, docId, object)` to update individual fields in a document. This method allows you to specify the collection path, document ID, and the fields to update in the form of an object. It will only update the fields provided in the object while keeping the existing data in the document intact.
|
|
601
635
|
|
|
602
636
|
```javascript
|
|
603
637
|
<script setup>
|
|
@@ -609,8 +643,9 @@ edgeFirebase.changeDoc("myItems", docId, updateItem);
|
|
|
609
643
|
|
|
610
644
|
In this example, the `changeDoc` method will update the title field of the specified document with the new value while preserving other fields. This is particularly useful when you need to modify a single field or a subset of fields in a document without affecting the rest of the data.
|
|
611
645
|
|
|
612
|
-
### Getting a single Document
|
|
613
|
-
If you want to query a single document from a collection use: **edgeFirebase.getDocData(collectionPath, docId)**
|
|
646
|
+
### Getting a single Document
|
|
647
|
+
If you want to query a single document from a collection, use: **edgeFirebase.getDocData(collectionPath, docId)**
|
|
648
|
+
|
|
614
649
|
```javascript
|
|
615
650
|
<script setup>
|
|
616
651
|
const docId = "DrJRpDXVsEEqZu0UB8NT";
|
|
@@ -657,8 +692,6 @@ To start a snapshot listener on a specific document within a collection, use the
|
|
|
657
692
|
|
|
658
693
|
Once you have started a snapshot listener on a document, reactive data for that snapshot will be available with `edgeFirebase.data[collectionPath + '/' + docId]`. This method first checks if the user has read permission for the specified document. If the user has permission, it starts the snapshot listener and updates the reactive data object accordingly. If the user doesn't have permission, it returns an error message indicating the lack of read access.
|
|
659
694
|
|
|
660
|
-
|
|
661
|
-
|
|
662
695
|
### Snapshot listeners can also be queried, sorted, and limited.
|
|
663
696
|
|
|
664
697
|
#### Query and Sort are an array of objects, Limit is a number
|
|
@@ -727,6 +760,7 @@ interface FirestoreOrderBy {
|
|
|
727
760
|
}
|
|
728
761
|
```
|
|
729
762
|
|
|
763
|
+
|
|
730
764
|
### Pagination
|
|
731
765
|
|
|
732
766
|
For pagination purposes there are 2 functions **staticSearch.next()** and **staticSearch.prev()**
|
|
@@ -861,8 +895,6 @@ rules_version = '2';
|
|
|
861
895
|
// #EDGE FIREBASE RULES END
|
|
862
896
|
```
|
|
863
897
|
|
|
864
|
-
|
|
865
|
-
|
|
866
898
|
## License
|
|
867
899
|
|
|
868
|
-
[ISC](https://choosealicense.com/licenses/isc/)
|
|
900
|
+
[ISC](https://choosealicense.com/licenses/isc/)
|
package/edgeFirebase.ts
CHANGED
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
OAuthProvider,
|
|
47
47
|
browserPopupRedirectResolver,
|
|
48
48
|
signInWithPopup,
|
|
49
|
+
updateEmail,
|
|
49
50
|
} from "firebase/auth";
|
|
50
51
|
|
|
51
52
|
import { getFunctions, httpsCallable, connectFunctionsEmulator } from "firebase/functions";
|
|
@@ -238,6 +239,23 @@ export const EdgeFirebase = class {
|
|
|
238
239
|
return await callable(data);
|
|
239
240
|
};
|
|
240
241
|
|
|
242
|
+
public updateEmail = async (newEmail: string): Promise<actionResponse> => {
|
|
243
|
+
try {
|
|
244
|
+
await updateEmail(this.auth.currentUser, newEmail);
|
|
245
|
+
return {
|
|
246
|
+
success: true,
|
|
247
|
+
message: "Email updated",
|
|
248
|
+
meta: {}
|
|
249
|
+
};
|
|
250
|
+
} catch (error) {
|
|
251
|
+
return {
|
|
252
|
+
success: false,
|
|
253
|
+
message: error.message,
|
|
254
|
+
meta: {}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
241
259
|
public logAnalyticsEvent = (eventName: string, eventParams: object = {}) => {
|
|
242
260
|
if (this.anaytics) {
|
|
243
261
|
logEvent(this.anaytics, eventName, eventParams);
|