Webcom SDK for JavaScript version 3.X provides a new API style.
The main innovation is a clear separation between a Webcom application and the Webcom services available on this application.
Using the 3.X API
1. Create an instance of WebcomApp
const app = Webcom.App("<your-app>");
Each instance of WebcomApp
manages exactly one instance of each available Webcom
service through dedicated properties:
authentication
for the Authentication service,serverlessDb
for the Serverless Database service.
Each service is actually initialized at the first access to its corresponding getter. For example, if you only use
the authentication
property of your WebcomApp
instance, its Serverless Database service will never be
initialized, and so its associated websocket will never be opened.
Also, configuration data may be passed to each Webcom service through the second argument of the Webcom.App
factory function:
const app = Webcom.App("<your-app>", {
ServerlessDb: {connect: false}, // see /doc/sdk/#webcom-sdk-js?/ServerlessDb.html#.Configuration
Authentication: {storage: "myAuthKey"}, // see /doc/sdk/#webcom-sdk-js?/Authentication.html#.Configuration
});
⚠ Warning ⚠
Be aware that each instance of
WebcomApp
manages its own instances of Authentication and Serverless Database instances!
As a consequence, an application should create only one instance ofWebcomApp
, otherwise it is likely to manage several Serverless Database instances, and so to open several websockets to the Webcom back end, which is generally not recommended: see details below.
2. Using the Authentication service
The name of each sign-in method is prefixed with signIn
(instead of auth
or authWith
in API 2.X):
app.authentication.signInAsGuest()
.then(authDetails => console.log("Signed-in with", auth.provider, "as", authDetails.uid))
.catch(error => console.log("Could not sign in:", error.message));
The sign-out method is signOut()
instead of logout()
:
app.authentication.signOut().then(() => console.log("Signed out!"));
All other authentication methods (available on 2.X Webcom
instances) remain available on the 3.X app.authentication
object. For example:
app.authentication.removeIdentity()
.then(() => console.log("Identity removed!"))
.catch(error => console.log("Failed to remove identity:", error.message));
3. Using the Serverless Database service
The main changes apply to the Serverless Database service.
General operations are directly available on the serverlessDb
property (and are roughly the same as the ones
available on the deprecated datasync
property of the Webcom
class). For example:
app.serverlessDb.connect(); // establish the websocket of the Serverless Database service
app.serverlessDb.disconnect(); // shuts the websocket down
Whereas operations related to data nodes (reading, writing, subscribing) need to get first a
ServerlessDbNode
instance. It can be retrieved using the
rootNode
property, combined with the
relativeNode
method:
const node = db.rootNode.relativeNode("/the/node/path");
For example, subscribing to the addition of new children on this node can be done as following:
const callback = Webcom.Callback(s => console.log("New child", s.node.key, "with value", s.val()))
.includeAcknowledgements();
let subscription;
node.subscribe(Webcom.Event.Child.Addition, callback)
.then(s => subscription = s)
.catch(error => "Subscription failed:", error.message);
While the corresponding unsubscription is implemented as either:
subscription.cancel();
or:
node.unsunscribe(callback);
Migrating from the 2.X API to the 3.X API
The following table gives a wide (although not exhaustive) correspondence between API 2.X calls and API 3.X ones:
API 2.X | API 3.X |
---|---|
Initialization operations |
|
const ref = new Webcom("<your-app"); |
const app = Webcom.App("<your-app>"); ⚠see belowconst db = app.serverlessDb; const auth = app.authentication; |
const ref = new Webcom("<your-app", config); |
const app = Webcom.App("<your-app>", config); ⚠see belowconst db = app.serverlessDb; const auth = app.authentication; |
Browsing operations |
|
const node = ref.child("sub/path"); |
const node = db.rootNode.relativeNode("sub/path"); |
node = node.parent(); |
node = node.parent; |
const name = node.name(); |
const name = node.key; |
const path = node.pathString(); |
const path = node.path; |
Writing operations |
|
node.set("value"); |
node.set("value"); |
node.onDisconnect().set("value"); |
node.set("value", Webcom.NEXT_DISCONNECTION); |
node.onDisconnect().cancel(); |
node.cancelNextDisconnectionOps(); |
node = node.push("value"); |
node.push("value").then(key => node = node.relativeNode(key)); |
const time = Webcom.pushIdToDateTime(node.name()); |
const time = node.timestamp.valueOf(); |
const uniqueKey = node.push().name(); |
const uniqueKey = db.generateUniqueKey(); |
Reading operations |
|
node.get().then(s => console.log(s.val())); |
node.get().then(s => console.log(s.val())); |
console.log(node.getCache().val()); |
console.log(node.getCache().val()); |
node.startAt("h").get().then(s => console.log(s.val())); |
node.get(Webcom.Constraint.StartAt("h")).then(s => console.log(s.val())); |
Subscription operations with callbacks |
|
node.on(["value","value_ack"], s => console.log(s.val())); |
const callback = Webcom.Callback(s => console.log(s.val())).includeAcknowledgements(); node.subscribe(Webcom.Event.ValueChange, callback); |
node.on("value", s => console.log(s.val()), () => Webcom.KEEP); |
const callback = Webcom.Callback(s => console.log(s.val()), Webcom.KEEP); node.subscribe(Webcom.Event.ValueChange, callback); |
const callback = node.limit(2).on("value", s => console.log(s.val())); |
const callback = Webcom.Callback(s => console.log(s.val())); node.subscribe(Webcom.Event.ValueChange, callback, Webcom.Constraint.Last(2)); |
node.off("value", callback); |
node.unsubscribe(callback); |
node.off(); |
not available |
Subscription operations with webhooks |
|
const webhook = Webcom.Webhook("id","context"); node.subscribe(Webcom.Event.ValueChange, webhook); |
unchanged |
node.unsubscribe(webhook, true); |
unchanged |
Connection operations |
|
const dbState = ref.datasync.currentState; |
const dbState = db.currentState; |
console.log(ref.datasync.shouldBeConnected ? "should" : "should not", "be connected"); |
console.log(db.shouldBeConnected ? "should" : "should not", "be connected"); |
ref.datasync.connect(); |
db.connect(); |
ref.datasync.disconnect(); |
db.disconnect(); |
Cache-related operations |
|
const data = ref.datasync.offlineData; |
const data = db.offlineData; |
ref.datasync.persist(); |
db.persist(); |
ref.datasync.cleanOfflineData(); |
db.cleanOfflineData(); |
Authentication operations |
|
ref.addAuthCallback((err, auth) => { ... }); |
auth.subscribe((err, state) => { const auth = state.details; ... } |
ref.logout(); |
auth.signOut(); |
ref.authAnonymously().then(authDetails => console.log(authDetails)); |
auth.signInAsGuest().then(authDetails => console.log(authDetails)); |
ref.authInternally("password", {id:"foo@bar.com", password:"123"}); |
auth.signInWithCredentials("password", {id:"foo@bar.com", password:"123"}); |
any other ref.authWithXXX(...) method |
auth.signInWithXXX(...) method |
any other ref.XXX(...) authentication-related method |
auth.XXX(...) method |
Warnings
1. WebcomApp
should be instantiated only once
In v2.X a Webcom
instance was a ref
obtained via a 'ref = new Webcom(...)
', it was “the entry point
for all classes, functions and properties of the Webcom SDK” but also a reference on a data node. So working
with multiples nodes of a same database could lead to instantiate the Webcom
class multiple times, one time for each
node, which was not an issue and was considered as a “normal way of working”.
In v3.X, on the contrary, the WebcomApp
class should be instantiated only once. Such an instance is built
by invoking the App
property of the Webcom
object. It owns a unique serverlessDb
property that manages the
ServerlessDb Service, which in turns manages the websocket to the Webcom back end. Instantiating several
WebcomApp
objects leads to open several websocket to the back end, which is generally not recommended (except
in specific cases, see below).
With this new API, accessing to different nodes is then possible via the rootNode
property of the serverlessDb
service and then the relativeNode()
method of the obtained ServerlessDbNode
object. If you need working with
several database nodes, then invoke several times the rootNode
property to get several ServerlessDbNode
instances, but invoke the Webcom.App()
method only once and share the obtained WebcomApp
instance all
across your JavaScript application.
Let's illustrate this in an example:
// connecting to my app
const app = Webcom.App("myPersonalApp"); // creates a WebcomApp instance, to be shared all across the JS application
const auth = app.authentication; // get the Authentication Service from the shared WebcomApp object
const database = app.ServerlessDb; // get the ServerlessDb Service from the shared WebcomApp object, this opens the websocket
// then authenticating
auth.signInWithCredentials({email: "me@orange.com", password: "myPassword"});
// then making many things...
// ...
// then, later, accessing to one of my user in database
let user, node;
user = "John";
node = database.rooNode.relativeNode(`/${user}`); // create a new node from the ServerlessDb Service
// making some stuff with this user...
// then moving to another user
user = "Paul";
node = database.rooNode.relativeNode(`/${user}`); // create a new node from the ServerlessDb Service
// making some stuff with this user...
//...
2. Specific case where to create many instances of WebcomApp
Managing two different authentication services on the same WebcomApp
instance is not possible.
If needed you can create two separate instances of this same application, each of them linked to a different
authentication service:
const appWithAuthent1 = Webcom.App("myApp"); // get a first instance of WebcomApp to "myApp"
const auth1 = appWithAuthent1.authentication; // get the Authentication Service of instance #1
auth1.signInWithCredentials({email: "me@orange.com", password: "myPassword"});
const database1 = appWithAuthent1.serverlessDb; // get the ServerlessDb Service of instance #1,
// which opens a websocket authenticated with auth1
const appWithAuthent2 = Webcom.App("myApp"); // get a second instance of WebcomApp to "myApp"
const auth2 = appWithAuthent2.authentication; // get the Authentication Service of instance #2
auth2.signInAsGuest();
const database2 = appWithAuthent2.serverlessDb; // get the ServerlessDb Service of instance #2,
// which opens another websocket authenticated with auth2
// then database1 is the root point to work on database with auth1
// and database2 is the root point to work on database with auth2
// ==> this results in 2 websockets to the back end, one for each authentication