Meteor: Can't replace document in restricted collection - meteor

I am using Meteor 4.2 (Windows) and I am always getting the "update failed: 403 -- Access denied. Can't replace document in restricted collection" when I am trying to update an object in my collection. Strangely I had no problem inserting new ones, only updates are failing.
I tried to "allow" everything on my collection:
Maps.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; },
fetch: function () { return true; }
});
But still, this update fails:
Maps.update({
_id: Session.get('current_map')
}, {
name: $('#newMapName').val()
});
Is there something else I can check? Or maybe my code is wrong? Last time I played with my project was with a previous version of Meteor (< 4.0).
Thanks for your help.
PS: Just for information, when I do this update, the local collection is updated, I can see the changes in the UI. Then very quickly it is reverted along with the error message, as the changes has been rejected by the server-side.

Alright, the syntax was actually incorrect. I don't understand really why as it was working well before, but anyway, here is the code that works fine:
Maps.update({
Session.get('current_map')
}, {
$set: {
name: $('#newMapName').val()
}
});

It seems like it must be related to what you're storing in the 'current_map' session variable. If it's a db object, then it probably looks like {_id:<mongo id here>} which would make the update finder work properly.
I ran into the same issues, and found the following to work
Blocks.update {_id:block_id}, {$set: params}
where params is a hash of all the bits i'd like to update and block_id is the mongo object id of the Block i'm trying to update.
Your note about the client side update (which flashes the update and then reverts) is expected behavior. If you check out their docs under the Data and Security section:
Meteor has a cute trick, though. When a client issues a write to the server, it also updates its local cache immediately, without waiting for the server's response. This means the screen will redraw right away. If the server accepted the update — what ought to happen most of the time in a properly behaving client — then the client got a jump on the change and didn't have to wait for the round trip to update its own screen. If the server rejects the change, Meteor patches up the client's cache with the server's result.

Related

Delete multiple records in an Azure Table

I have a mobile app written using Apache Cordova. I am using Azure Mobile Apps to store some data.
I created Easy Tables and 1 Easy API. The purpose of the API is to perform delete / update more than 1 record. Below is the implementation of the API.
exports.post = function (request, response){
var mssql = request.service.mssql;
var sql = "delete from cust where deptno in ( ? )";
mssql.query(sql, [request.parameters],{
success : function(result){ response.send(statusCodes.OK, result); },
error: function(err) { response.send(statusCodes.BAD_REQUEST, { message: err}); }
});
}
Is there any other way to implement it ? The del() method on table object on takes id to delete and I didn't find any other approach to delete multiple rows in the table.
I am having difficulty to test the implementation as the changes in the API code is taking 2-3 hours on average to get deployed. I change the code through Azure website and when I run it, the old code is hit and not the latest changes.
Is there any limitation based on the plans we choose?
Update
The updated code worked.
var sql = "delete from trollsconfig where id in (" + request.body.id + ")";
mssql.query(sql, [request.parameters],{
success : function(result){ response.send(statusCodes.OK, result); },
error: function(err) { response.send(statusCodes.BAD_REQUEST, { message: err}); }
});
Let me cover the last one first. You can always restart your service to use the latest code. The code is probably there but the Easy API change is not noticing it. Once your site "times out" and goes to sleep, the code gets reloaded as normal. Logging onto the Azure Portal, selecting your site and clicking Restart should solve the problem.
As to the first problem - there are a variety of ways to implement deletion, but you've pretty much got a good implementation there. I've not run it to test it, but it seems reasonable. What don't you like about it?

Meteor IronRouter waitOn Infinite loop

I have a pretty standard setup for my meteor app using IronRouter. What I am having problems with is this, I am attempting to redirect someone to a page based on some tokens in a url coming from a third party website but when the user is sent to their destination from the Accounts.onLogin callback via Router.go("some/fun/url"); the waitOn function runs endlessly.
Below is the pertinent part of the setup.
First the route that I am redirecting to:
Router.route("/shows/:show_acronym/sponsorships", {
name:"sponsorshipsSalesPortal",
data:function(){
return {show:Shows.findOne({acronym:this.params.show_acronym})};
},
waitOn:function(){
console.log("wait on");
return [Meteor.subscribe("show_by_acronym",this.params.show_acronym),Meteor.subscribe("catalogue_products_by_acronym", this.params.show_acronym)];
}
});
Next the relevant part of the onLogin hook:
Accounts.onLogin(function(){
if (Session.get("showToRedirectTo")){
console.log("sending to sponsorship portal");
var ur ="/shows/"+Session.get("showToRedirectTo")+"/sponsorships"
return Router.go(ur);
}
});
When it hits the redirect, the url changes and the message "wait on" prints in the console forever. Does anyone know of a solution to this? I would prefer to keep all of my subscriptions at the router level if at all possible.
Thanks
You should only return subscription cursors (Meteor.subscribe(*)) in the waitOn return array.
In your case, "this.params.show_acronym" is the problem...
Actually your code looks good, its been a while since i dont use Iron Router or Sessions.
But looking at the WaitOn, it seems okay, the problem can come from the Server side where show_by_acronym or catalogue_products_by_acronym its throwing an error, but in all the cases this should cause you to get a spinner loading forever, not a console.log("wait on"); printed forever.
so i think your Accounts.onLogin is causing this.
Try something like.
Accounts.onLogin(function(){
if (Session.get("showToRedirectTo")){
console.log("sending to sponsorship portal");
var ur ="/shows/"+Session.get("showToRedirectTo")+"/sponsorships"
Router.go(ur);
Session.set('showToRedirectTo', false)
}
});

Firebase and Angularfire nightmare migration for Update

I am new to firebase and I am having a bit of a nightmare trying to adapt old code to what is now deprecated and what is not. I am trying to write a function which updates one "single" record in my datasource using the now approved $save()promise but it is doing some really strange stuff to my data source.
My function (should) enables you to modify a single record then update the posts json array. However, instead of doing this, it deletes the whole datasource on the firebase server and it is lucky that I am only working with testdata at this point because everything would be gone.
$scope.update = function() {
var fb = new Firebase("https://mysource.firebaseio.com/Articles/" + $scope.postToUpdate.$id);
var article = $firebaseObject(ref);
article.$save({
Title: $scope.postToUpdate.Title,
Body: $scope.postToUpdate.Body
}).then(function(ref) {
$('#editModal').modal('hide');
console.log($scope.postToUpdate);
}, function(error) {
console.log("Error:", error);
});
}
Funnily enough I then get a warning in the console "after" I click the button:
Storing data using array indices in Firebase can result in unexpected behavior. See https://www.firebase.com/docs/web/guide/understanding-data.html#section-arrays-in-firebase for more information. Also note that you probably wanted $firebaseArray and not $firebaseObject.
(No shit?) I am assuming here that $save() is not the right call, so what is the equivalent of $routeParams/$firebase $update()to do a simple binding of the modified data and my source? I have been spending hours on this and really don't know what is the right solution.
Unless there's additional code that you've left out, your article $firebaseObject should most likely use the fb variable you created just before it.
var article = $firebaseObject(fb);
Additionally, the way in which you're using $save() is incorrect. You need to modify the properties on the $firebaseObject directly and then call $save() with no arguments. See the docs for more.
article.Title = $scope.postToUpdate.Title;
article.Body = $scope.postToUpdate.Body;
article.$save().then(...

Ember-Pouch not syncing?

I like to fix the cross brower sync in https://github.com/broerse/ember-cli-blog. If I swap out the adapter for a Firebase adapter everything works as expected. (See https://github.com/broerse/ember-cli-blog-fire) It can be some CouchDB setup error on my side but there are no errors in the console. Is there some simple thing I keep overlooking?
Modified the ember-pouch readme to fix this, but to answer here: what you need to do is add
afterModel: function (recordArray) {
// This tells PouchDB to listen for live changes and
// notify Ember Data when a change comes in.
new PouchDB('mydb').changes({
since: 'now',
live: true
}).on('change', function () {
recordArray.update();
});
}

The earliest point I can get a Meteor.user()

I want to update my user status to be online, meaning, run this code (coffee script...)
Meteor.users.update _id: Meteor.user()._id, $set: 'profile.idle': true, 'profile.online': true if Meteor.user()?
I don't know where to put it, (is it ok to put it in client? ) where will this code run for sure with the logged in user even if user already logged in before ?
from little googling I found that meteor start events is not the place, what is the place?
client side in a Deps.autorun block would do it
in js it would be something like
Deps.autorun(function(){
if(Meteor.user()){
Meteor.users.update(Meteor.userId(),{$set:{<your fields here>}});
}
});
--
if you are trying to detect that users are online and can use meteorite, you might want to check out https://atmosphere.meteor.com/package/profile-online
you could also roll your own, by setting up a Meteor.setInterval call every 10 seconds or so to update a lastSeen time for the user, then detect if the user is online if lastSeen > timeNow - userTimeout[60 seconds?]

Resources