Skip to content

Commit

Permalink
Implement Realm.User.push()
Browse files Browse the repository at this point in the history
  • Loading branch information
RedBeard0531 committed Jun 22, 2020
1 parent 77fb1fe commit 380ec27
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ NOTE: This version bumps the Realm file format to version 11. It is not possible

### Enhancements
* Added RemoteMongoClient functionality to `Realm.User`
* Added Push functionality to `Realm.User`

### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?)
Expand Down
27 changes: 27 additions & 0 deletions docs/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,33 @@ class User {
* @returns {Realm~RemoteMongoDB}
*/
remoteMongoClient(serviceName) { }

/**
* @class Realm.User~Push Access to the operations of the push service.
*/

/**
* Registers the provided token with this User's device.
*
* @function Realm.User~Push#register
* @param {string} token
* @returns {Promise<void>} completed when the user is registered, or the operation fails.
*/

/**
* Deregisters this User's device.
*
* @function Realm.User~Push#deregister
* @returns {Promise<void>} completed when the user is deregistered, or the operation fails.
*/

/**
* Access the operations of the push service.
*
* @param {string} serviceName
* @returns {Realm.User~Push}
*/
push(serviceName) { }
}

/**
Expand Down
2 changes: 2 additions & 0 deletions lib/browser/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ createMethods(User.prototype, objectTypes.USER, [
"_deleteUser",
"_linkCredentials",
"_callFunction",
"_pushRegister",
"_pushDeregister",
]);

Object.defineProperties(User.prototype, {
Expand Down
12 changes: 12 additions & 0 deletions lib/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ const instanceMethods = {
};
},

push(serviceName) {
const user = this;
return {
register(token) {
return promisify(cb => user._pushRegister(serviceName, token, cb));
},
deregister() {
return promisify(cb => user._pushDeregister(serviceName, cb));
},
};
},

_functionsOnService(service) {
const user = this;
return new Proxy({}, {
Expand Down
1 change: 1 addition & 0 deletions realm.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
"src/object-store/src/sync/remote_mongo_collection.cpp",
"src/object-store/src/sync/remote_mongo_database.cpp",
"src/object-store/src/sync/generic_network_transport.cpp",
"src/object-store/src/sync/push_client.cpp",
"src/object-store/src/util/bson/bson.cpp",
"src/object-store/src/util/bson/regular_expression.cpp",
],
Expand Down
5 changes: 4 additions & 1 deletion src/js_app_credentials.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,11 @@ template<typename T>
void CredentialsClass<T>::function(ContextType ctx, ObjectType this_object, Arguments& arguments, ReturnValue& return_value) {
arguments.validate_count(1);
const std::string payload_json = Value::validated_to_string(ctx, arguments[0], "payload");
const auto payload_bson = bson::parse(payload_json);
if (payload_bson.type() != bson::Bson::Type::Document)
throw std::invalid_argument("payload must be a json object");

auto credentials = realm::app::AppCredentials::function(payload_json);
auto credentials = realm::app::AppCredentials::function(payload_bson.operator const bson::BsonDocument&());
return_value.set(create_object<T, CredentialsClass<T>>(ctx, new app::AppCredentials(credentials)));
}

Expand Down
2 changes: 1 addition & 1 deletion src/js_network_transport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ struct JavaScriptNetworkTransport : public JavaScriptNetworkTransportWrapper<T>
case app::HttpMethod::get: return "GET";
case app::HttpMethod::put: return "PUT";
case app::HttpMethod::post: return "POST";
case app::HttpMethod::del: return "DEL";
case app::HttpMethod::del: return "DELETE";
case app::HttpMethod::patch: return "PATCH";
default: throw std::runtime_error("Unknown HttpMethod argument");
}
Expand Down
51 changes: 51 additions & 0 deletions src/js_user.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class UserClass : public ClassDefinition<T, User<T>> {
static void link_credentials(ContextType, ObjectType, Arguments&, ReturnValue&);
static void call_function(ContextType, ObjectType, Arguments&, ReturnValue&);
static void refresh_custom_data(ContextType, ObjectType, Arguments&, ReturnValue&);
static void push_register(ContextType, ObjectType, Arguments&, ReturnValue&);
static void push_deregister(ContextType, ObjectType, Arguments&, ReturnValue&);


MethodMap<T> const methods = {
Expand All @@ -104,6 +106,8 @@ class UserClass : public ClassDefinition<T, User<T>> {
{"_linkCredentials", wrap<link_credentials>},
{"_callFunction", wrap<call_function>},
{"_refreshCustomData", wrap<refresh_custom_data>},
{"_pushRegister", wrap<push_register>},
{"_pushDeregister", wrap<push_deregister>},
};
};

Expand Down Expand Up @@ -303,5 +307,52 @@ void UserClass<T>::refresh_custom_data(ContextType ctx, ObjectType this_object,
}));
}

template<typename T>
void UserClass<T>::push_register(ContextType ctx, ObjectType this_object, Arguments& args, ReturnValue &return_value) {
args.validate_count(3);
auto user = get_internal<T, UserClass<T>>(ctx, this_object);
auto service = Value::validated_to_string(ctx, args[0], "service");
auto token = Value::validated_to_string(ctx, args[1], "token");
auto callback = Value::validated_to_function(ctx, args[2], "callback");

user->m_app->push_notification_client(service).register_device(
token,
*user,
realm::util::EventLoopDispatcher([ctx = Protected(Context<T>::get_global_context(ctx)),
callback = Protected(ctx, callback),
this_object = Protected(ctx, this_object)]
(util::Optional<app::AppError> error) {
HANDLESCOPE(ctx);
Function::callback(ctx, callback, this_object, {
!error ? Value::from_undefined(ctx) : Object::create_obj(ctx, {
{"message", Value::from_string(ctx, error->message)},
{"code", Value::from_number(ctx, error->error_code.value())},
}),
});
}));
}

template<typename T>
void UserClass<T>::push_deregister(ContextType ctx, ObjectType this_object, Arguments& args, ReturnValue &return_value) {
args.validate_count(2);
auto user = get_internal<T, UserClass<T>>(ctx, this_object);
auto service = Value::validated_to_string(ctx, args[0], "service");
auto callback = Value::validated_to_function(ctx, args[1], "callback");

user->m_app->push_notification_client(service).deregister_device(
*user,
realm::util::EventLoopDispatcher([ctx = Protected(Context<T>::get_global_context(ctx)),
callback = Protected(ctx, callback),
this_object = Protected(ctx, this_object)]
(util::Optional<app::AppError> error) {
HANDLESCOPE(ctx);
Function::callback(ctx, callback, this_object, {
!error ? Value::from_undefined(ctx) : Object::create_obj(ctx, {
{"message", Value::from_string(ctx, error->message)},
{"code", Value::from_number(ctx, error->error_code.value())},
}),
});
}));
}
}
}
17 changes: 17 additions & 0 deletions tests/js/user-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,23 @@ module.exports = {
TestCase.assertEqual(await collection.count({hello: "pineapple"}), 0);
},

async testPush() {
let app = new Realm.App(appConfig);
let credentials = Realm.Credentials.anonymous();
let user = await app.logIn(credentials);

let push = user.push('gcm');

await push.deregister(); // deregister never registered not an error
await push.register("hello");
await push.register("hello"); // double register not an error
await push.deregister();
await push.deregister(); // double deregister not an error

const err = await TestCase.assertThrowsAsync(async() => await user.push('nonesuch').register('hello'))
TestCase.assertEqual(err.message, "service not found: 'nonesuch'");
},

async testAllWithAnonymous() {
let app = new Realm.App(appConfig);
await logOutExistingUsers(app);
Expand Down
4 changes: 4 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ declare namespace Realm {
linkCredentials(credentials: Credentials): Promise<void>;
callFunction(name: string, args: any[]): Promise<any>;
refreshCustomData(): Promise<Object>;
push(serviceName: string): {
register(token: string): Promise<void>,
deregister(): Promise<void>,
};

readonly apiKeys: Realm.Auth.APIKeys;
}
Expand Down

0 comments on commit 380ec27

Please sign in to comment.