I'm currently programming a background job for my Parse Database.
The Database contains lots of users in the User class. All user have a 'location' column and an 'offer' and 'search' column. 'offer' and 'search' store an array of strings.
What it should do is the following:
The background job should go through all the users and check for users close to them and then check if these users match on specific skills. So if someone has "example" in 'search' and someone else has "example" in 'offer' these user match and both get a notification.
The location query does not choose users close to each other
If a user does not "offer" anything, but "searches" for something he does not get a notification
It should not constantly send push notifications when two users are close to each other (only once)
-
Parse.Cloud.job("backgroundJob", function(request, status) {
var queryAllUser = new Parse.Query(Parse.User);
Parse.Cloud.useMasterKey();
var targetList = []; //new Array();
queryAllUser.each(function(user) {
var queryMatch = new Parse.Query(Parse.User);
queryMatch.withinKilometers("location", user.get("location"), 0.1);
//if(user.get("search") != null){
queryMatch.containedIn("offer", user.get("search"));
// }
return queryMatch.first().then(function(firstUser) {
if (firstUser != null) {
console.error("THIS IS THE FIRST USER: " + firstUser.get("name"));
}
if (firstUser) {
targetList.push(user);
}
});
}).then(function() {
console.error("Length of TargetList: " + targetList.length);
if (targetList[0] != null && targetList.length != 1) {
var queryTarget = new Parse.Query(Parse.Installation);
queryTarget.containedIn('user', targetList);
return Parse.Push.send({
where: queryTarget,
data: {
alert: "Found a Match!",
badge: "Increment",
pushType: "1",
}
}, {
success: function() {
status.success("Send the Pushes!");
},
error: function(error) {
status.error(error);
}
});
}
status.success("did the job!");
},
function(error) {
status.error("error:" + error.message);
});
});
Related
I'm creating a Chrome Extension right now, and I'm running into a problem where the same notification is created and displayed a bunch of times. I was wondering if there is a solution on how to check and make sure that if there is already a notification, to not create a new one. Here's my code on how the notifications are created:
async function alert() {
console.log("Alert getting created");
var result = await getExpiredIndices();
var numberOfExpiredTabs = result.expiredTabArray.length;
var id = uuidv4();
var msg = `Ta daa! Your tab(s) are ready.`;
chrome.notifications.create(
id,
{
type: "basic",
iconUrl: "assets/icons/pondr_128.png",
title: "Pondr",
message: msg,
priority: 2,
requireInteraction: true,
buttons: [
{
//get indexes from storage pop them when user re-opens tabs
title: "Open",
},
{
title: "Later",
//get indexes, shift all times, pop them since they are no longer in the outdated subarray
},
],
}
);
}
chrome.notifications.onButtonClicked.addListener(async function (
notifId,
btnIdx
) {
var result1 = await getExpiredIndices();
var result2 = await getAllTabsArray();
var expiredTabArray = await result1.expiredTabArray;
var allTabsArray = await result2.allTabsArray;
if (btnIdx === 0) {
//if yes open tabs
console.log("hit yes");
console.log("Before popping allTabsArray: ", allTabsArray);
console.log("Before popping expiredTabsArray: ", expiredTabArray);
openTabsNow(expiredTabArray, allTabsArray);
} else if (btnIdx === 1) {
console.log("hit later");
console.log("Before popping allTabsArray: ", allTabsArray);
console.log("Before popping expiredTabsArray: ", expiredTabArray);
openTabsLater(expiredTabArray, allTabsArray);
//if no reapply reminder-setting
//FOR TIME BEING: will be hardcoded to push all items 3 hrs forward
}
});
Currently I try to integrate amazon payment.
I want to display the button, created with the function:
OffAmazonPayments.Button("AmazonPayButton", myAmznMerchantID
and after the User has logged in, I want to display the AdressBook Widget and the Payment Widget on the same Page.
The Button and the Widgets are displayed correctly, but when I try to confirm the Payment, I'm getting the Error-Constrains Message:
PaymentPlanNotSet The buyer has not been able to select a Payment
method for the given Order Reference.
But the Payment was selected.
I hope you can help me, to find my failure in this Javascript code:
window.onAmazonLoginReady = function () {
amazon.Login.setClientId(myAmznClientID);
};
window.onAmazonPaymentsReady = function() {
var __accessToken = 0;
var __orderReferenceId = 0;
show_amazon_Button();
function show_amazon_Button() {
OffAmazonPayments.Button("AmazonPayButton", ibuiAmazonPaymentsInfos.ibAmznMerchantID, {
type: "PwA",
color: "Gold",
size: "small", // "medium",
language: "de-DE",
authorization: function () {
loginOptions = { scope: "profile:user_id", popup: true };
authRequest = amazon.Login.authorize(loginOptions, function(response) {
if (response.error) {
//show Error
return;
} else {
__accessToken = response.access_token;
show_Adress_Widget();
}
});
},
onError: function(error) {
//handleError
}
});
}
function show_Adress_Widget() {
new OffAmazonPayments.Widgets.AddressBook({
sellerId: ibuiAmazonPaymentsInfos.ibAmznMerchantID,
onOrderReferenceCreate: function (orderReference) {
__orderReferenceId = orderReference.getAmazonOrderReferenceId();
//do Stuff
},
onAddressSelect: function (orderReference) {
show_Amazon_Wallet();
},
design: {
designMode: 'responsive'
},
onError: function (error) {
//handle Error
}
}).bind("readOnlyAddressBookWidgetDiv");
}
function show_Amazon_Wallet() {
new OffAmazonPayments.Widgets.Wallet({
sellerId: myAmznMerchantID,
onOrderReferenceCreate: function(orderReference) {
//do Stuff
},
design: {
designMode: 'responsive'
},
onPaymentSelect: function(orderReference) {
//activate buy button
},
onError: function(error) {
//handle error
}
}).bind('AmazonWalletWidgetDiv');
}
} //onAmazonPaymentsReady
In PHP I create the OrderReference over:
$params = array(
'order_reference_id' => $orderReferenceId,
'amount' => $amount,
'seller_order_id' => $buchungsKopf->getBuchung_nr(),
);
$responseObject = $client->setOrderReferenceDetails($params);
And even if I had selected a payment method before, I'm getting the "PaymentPlanNotSet" in the responseObject.
Same error, when I try to confirm the orderReference
$responseObject2 = $client->confirmOrderReference($params);
Before I had integrate the AdressWidget, I was able to do the payment.
Can you see what I'm doing wrong?
It seems I have found my failure.
When I want to display both Widgets (Adress and Wallet) on the same page, then I can not use the onOrderReferenceCreate-Method in the OffAmazonPayments.Widget.Wallet.
It seems like then it create a new order reference wich is not the same as the orderreference created by the AdressBook Widget.
Now I have delete this part of the Wallet Widget and everything seems to work fine.
I have a json looking like so:
{
"itemsList": [{
"id": 187994,
"contentName": "Content",
"contentItems": [{
"name": "nested 1",
"description": "<p>nested 1</p>\n"
}, {
"name": "nested 2 ",
"description": "<p>nested 2</p>\n"
}]
}]
}
And I am importing this data to an update form and trying to update the value for nested 1 when I submit the form but it keeps only the updated value, somehow it keeps only the updated value the other values get wiped out.
The function below updates the contentItems object but it keeps only the updated content:
$("#editResourceItemForm").submit(function (e) {
e.preventDefault();
$.getJSON(appDirLocation + "public/_data/resource_data.json", function (jsonData) {
console.log(jsonData.itemsList.contentItem);
//var contentItems = jsonData.itemsList.contentItems;
var resourceId = $("#editResourceItemForm input#resourceId").val(); // resource id
var updatedContentName = $("#appData").data("content-name");
var updatedContentItem = {
name: $("#editResourceItemForm input#contentItemName").val(),
description: CKEDITOR.instances.contentItemDescription.getData()
};
resourceId = Number(resourceId); // input filed is collected as string needs to make number
_.each(jsonData.itemsList, function (item) {
if (item.id === resourceId) {
item.contentName = updatedContentName;
item.contentItems = updatedContentItem ;
// queue here new items to update
}
}); // used underscore.js seems better for handling json data
var newJsonOutput = JSON.stringify(jsonData); //stringify new data
var jsonFile = new BCAPI.Models.FileSystem.File(appDirLocation + "public/_data/resource_data.json");
jsonFile.upload(newJsonOutput).done(function () {
$("#contentItemsList").html(""); //clear old data to load new
console.log("RESOURCE DATA UPDATED");
$('#editResourceItem').foundation('close'); //close reveal after created and saved file
renderResourceItems(resourceId);
}).fail(function (jqXHR) {
console.log("RESOURCES JSON FAILED UPDATE: " + jqXHR.responseText);
}); // END OF JSON CREATING
console.log(newJsonOutput);
}).done(function (dataprocessed) {
console.log(dataprocessed);
}).fail(function (jqXHR) {
console.log("Request failed." + "Error code: " + jqXHR.status + "Error text: " + jqXHR.statusText + "Response text: " + jqXHR.responseText);
});
});
Please let me know what I can do to pass the updated values to the existing contentItems without wiping out the rest of the data in the object.
This is the fiddle I used to create the data:
https://jsfiddle.net/RicardoAlves/zb5dprvv
Thanks
Here is my function used to retrieve data from the database depending on the parameter idCats:
this.getSubcat = function(){
//Load products on scroll.
this.subscribe('SubcatIndex', () => [ $stateParams.idCats, self.loaded ], {
onReady: function() {
Meteor.call('allSubcats', $stateParams.idCats, function(err, count) {
self.allsubcats = count;
self.limit = self.loaded;
console.log("Test Log: " + $stateParams.idCats);
self.subcats = Products.find({
catLinkID : $stateParams.idCats
},{
fields: {
_id: true,
name: true,
catLinkID: true,
idCat: true,
image: true,
listingsCount: true,
productOffersCount: true,
productSoldCount: true
}
}).fetch();
window.localStorage.setItem('subcats', JSON.stringify(self.subcats) );
self.contentLoaded = true;
self.noPosts = 'No posts available.';
$ionicLoading.hide();
return;
});
},
onStop: function(err){
if(err){
self.contentLoaded = true;
self.noPosts = "No internet connection.";
console.log(JSON.stringify(err));
return;
}
}
});
}
this.getSubcat();
When i change this line:
self.subcats = Products.find({
catLinkID : $stateParams.idCats
}
To:
self.subcats = Products.find({
catLinkID : 7 // 7 for example
}
It is working well ! But as soon as I replace it with $stateParams.idCats, I receive this message coming from the function: No posts available.
Note that there are products using the idCats: 7.
When I log it:
console.log("Test Log: " + $stateParams.idCats);
This returns the same number: Test Log: 7.
If you have any suggestion or a starting point to solve this issue, it will be welcome !
Notice that there are no error in the Console (Both server and client side).
Thank you.
Is there a way to update the text on SweetAlert2 alert to show the number of rows that have been processed in a a really long javascript loop? Unfortunately people have been leaving the page and then only half the rows get saved.
I thought I might be able to use jQuery type syntax, but not sure what the proper select might be.
$('#rowsprocessed').text(count);
swal({
title: 'Save Order.',
input: 'checkbox',
inputValue: 0,
inputPlaceholder: 'Remove Zero(s) Quantity Item(s) Before Saving the Order?',
html: 'For large templates this may take a few moments. This message will automatically close when the process is complete.',
type: 'info',
showCancelButton: true,
confirmButtonText: 'Submit',
showLoaderOnConfirm: true,
preConfirm: function(checkbox) {
return new Promise(function(resolve, reject) {
removeZeros = checkbox;
setTimeout(function() {
swal.showLoading();
$.post("/components/com_sails/views/neworderform/saveOrderHeader.php",
{
orderid: orderid,
accountid: accountid,
buyerid: buyerid,
vendorid: vendorid,
ponumber: ponumber,
specialinstr: specialinstr,
orderDate: orderDate,
shipDate: shipDate,
cancelDate: cancelDate
},
function (result) {
if (result.return == 1) {
// assign order id to holder field
$('#orderInput').jqxInput('val', result.ordernbr);
// loop through our rows and save depending on the removeZero marker
var rows = $('#jqxgrid').jqxGrid('getdisplayrows');
var rowsToRemove = [];
var linessaved = 0;
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
// get row info for delete
if ((removeZeros == 1) && row['quantity'] == 0) {
rowsToRemove.push(row.uid);
}
// run database update
$.ajax({
type: 'POST',
url: '/components/com_sails/views/neworderform/saveOrderLine.php',
data: {
orderid: result.ordernbr,
removezeros: removeZeros,
rowdata: row
},
success: function (rowSaveData) {
// alert('rowSaveData ' + rowSaveData.return + " " + rowSaveData.isbn + " " + rowSaveData.action + " " + rowSaveData.msg + " row.uid: " + row.uid);
// if there is a problem what do we do????
if (rowSaveData.return == 1) {
$('#rowsprocessed').text(i);
}
if (rowSaveData.return == -1) {
// add to error message?
}
},
datatype: 'json',
async: false});
}
if (removeZeros == 1) {
// delete our zero rows
var commit = $("#jqxgrid").jqxGrid('deleterow', rowsToRemove);
$('#jqxgrid').jqxGrid('render');
lastselectedrow = -1;
}
// set save marker??
isDirty = false;
}
else {
// there was an error saving the header
// need to get this logged
alert('Error Saving Order. Details: ' + result.msg);
}
}, "json");
resolve();
}, 2000);
});
},
allowOutsideClick: false
}).then(function() {
swal({
type: 'success',
title: 'Order saved',
html: '<b><div id="rowsprocessed">0</div></b> rows saved.',
timer: 4000
});
})
Absolutely you can, you just pass in an additional element with your {html: "..."} that you can use as a means of updating the user.
Something Like:
{
...
html: 'For large templates this may take a few moments. This message will automatically close when the process is complete.<br/><span class="swal2- status"></span>',
...
}
And then use this syntax to update:
var $status = $('.swal2-status');
$status.html("I'm an update");
See the example here:
https://jsfiddle.net/1mvnxp3L/