Having trouble with Create-Only rules in Firebase Realtime Database - json

I'm trying to create a card deck database.
I have a node, "decks". Inside it are more nodes, numbered from '00001'. Inside '00001' is a node for each card, numbered appropriately, and inside each card node is the card data.
deck
00001
card001
SetCode:Alpha
SetID:001
card002
etc.
My problem is when it comes to the security rules. I don't want anyone to be able to update or delete any decks.
"decks":{
"$deckId":{
".validate": "$deckId.matches(/^[0-9]{5,5}$/) && $deckId.length == 5 && data.val() == null && newData.val() != null",
"$cardNumber":{
".validate": "$cardNumber.matches(/^[C][a][r][d][0](30|2[0-9]|1[0-9]|[0][1-9])$/) && $cardNumber.length == 7",
"SetCode":{".validate": "newData.isString()&& newData.val().matches(/^[A-Z][a-z]{4}$/)"},
"SetID":{".validate": "newData.isString()&& newData.val().matches(/^[0-9]{3}$/)"},
}}}
and I can't seem to find a set of rules that lets me make a new deck while also preventing anyone from deleting it or updating an existing deck.
Some rules I've tried are:
".write": "auth != null",
".write": "data.val() == null && newData.hasChildren() != null",
".write": "!data.exists()"
".write": "data.val() == null && newData.val() != null"
in various 'depths' of the rules, but I've been hitting my head against this for hours now. If someone could point me to the correct rule in the correct 'depth', I would be very grateful.
Edit: The main instance that I thought would work - and that I had found on multiple resources for Creation-Only rules, was:
'decks':{
".write": "data.val() == null && newData.val() != null",
}
It could be that I'm putting it in the wrong depth or if there's some other factor I haven't taken into account, but I don't understand why this doesn't work. I don't have any other read/write rules on higher levels.

The problem is where you defined the rule, not their contents.
You need to define the rule on the exact path where the write operation occurs. Since you want to allow creating a new deck, you need the rule to be on the individual deck, which you can do by using a wildcard variable:
'decks':{
"$deckid": {
".write": "!data.exist" // allows creation, but not updating or deletion
}
}

Related

Google Appscript IF Or statement not working

Good day everyone; I am running into an error I can't explain. The scenario is as follows, I have two input boxes that collect information. If no value is entered, I want the if statement to handle it and cause a break. The Input box also has an "x" to close the box, which returns a value of "Cancel". What I am trying to do is capture a condition where if no value is entered OR cancel is passed through, a break will occur. Right now, the problem is Google completely ignores the Or statement. I know individually, my IF logic works, but when coupled with OR it doesn't recognize the condition.
This is my current code:
var propnumber = Browser.inputBox('Enter RFI/RFQ Number', Browser.Buttons.OK);
if(propnumber != "" || propnumber != 'cancel'){} else{
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
};
var myName = Browser.inputBox("Enter the Component Name",Browser.Buttons.OK_CANCEL);
if(myName != 'cancel')
{
I do something
}
As I mentioned in my description, my propnumber condition ignores the or and always accepts the value of cancel or blank. If I remove the or ( || ) then it works with one condition at a time.
I am sure this is something trivial any help appreciated.
What's wrong
The logic in the following part of your code
if(propnumber != "" || propnumber != 'cancel'){
// I assume some code will go here
} else{
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
};
does not match the logic you've described here:
if no value is entered OR cancel is passed through, a break will occur.
Consider the case where propnumber is 'cancel':
propnumber != "" evaluates to true
propnumber != 'cancel' evaluates to false
Therefore the if(... || ...) condition in your code evaluates to true and the (currently empty) if block runs, rather than the else.
How to fix it
Option 1: A literal translation of the logic
if no value is entered OR cancel is passed through, a break will occur
would be
if(propnumber == "" || propnumber == 'cancel') {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
} else {
// Some action
}
Option 2: If you wish to swap the if and else clauses, you must negate the entire condition. So this will also work:
if(!(propnumber == "" || propnumber == 'cancel')) {
// Some action
} else {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
}
Note the added parentheses and single negation.
Option 3: use AND instead of OR in your existing code.
The expression !(A || B) is NOT logically equivalent to !A || !B. Instead, it is equivalent to !A && !B (see DeMorgan's Law). So this will also work:
if(propnumber != "" && propnumber != 'cancel') {
// Some action
} else {
SpreadsheetApp.getActiveSpreadsheet().toast('You must enter a value')
return
}

how to create only one chip from the same word in Angular

I'm wondering if there is away to make my input to create only one chip from the same word instead of creating duplicate.
Right now user seem like they can create "apple" "APPLE" "apPPle" "aPpLe" so I'm figuring out a way not do that and always return with lowercase "apple" even if they type something with all Uppercase or Lowercase.
I just want to create only one chip for one word. any help or suggestion will be really appreciated.
I have tried all this but still not working
1. this.value = $event.target.value.toUpperCase()
this.ngModelChange.emit(this.value)
2. event.value=event.value.toLowerCase()
3. {{ value | lowercase }}
If I can fix this, the user might able to create "apple" "apple" multiple time but later I will prevent user from imputing the same word if "apple" is already existed/created.
Here is the project that is very similiar with mine
https://stackblitz.com/edit/angular-occkra
You need to add filtering logic to select and add methods:
if ((value || '').trim()) {
if (this.allFruits.includes(value.toLowerCase()) && !this.fruits.includes(value.toLowerCase())) {
this.fruits.push(value.trim().toLowerCase());
}
}
without include
if ((value || '').trim()) {
if (this.allFruits.find((f) => f.toLowerCase() === value.toLowerCase()) && !this.fruits.find((f) => f.toLowerCase() === value.toLowerCase())) {
this.fruits.push(value.trim().toLowerCase());
}
}

DMF and Advanced accounting structure

I have 10 dimensions in standard accounting structure and 7 dimensions defined in advanced rule.
Importing journals through DMF in excel throws error for 17 dimensions but works with 10 dimensions.
What's the right way to resolve this?
I got the solution. The issue was in generateDynamicDimension() method in DmfDimensionHelper Class.
Although It was bringing in all the dimensions values from the Segmented Entry Dimension column from Excel Sheet, it was picking only those Dimension names from the table where DimensionHierarchyType is AccountStructure and not from the Advanced Rule. I included DimensionHierarchyType of AccountRuleStructure as well. Now it's working.
while select Level from dimHierarchyLevel
order by dimHierarchyLevel.DimensionHierarchy, dimHierarchyLevel.Level
where (dimHierarchyLevel.DimensionHierarchy == dimHierarchyId
&& dimHierarchy.IsDraft == false
&& dimHierarchy.IsSystemGenerated == false
&& (dimHierarchy.StructureType == DimensionHierarchyType::AccountStructure || dimHierarchy.StructureType == DimensionHierarchyType::AccountRuleStructure)
join * from dimAttribute where
dimAttribute.RecId == dimHierarchyLevel.DimensionAttribute
exists join ledgerStructure
where ledgerStructure.DimensionHierarchy == dimHierarchy.RecId
&& ledgerStructure.Ledger == Ledger::current()
This is the additional Condtition I entered:
dimHierarchy.StructureType == DimensionHierarchyType::AccountRuleStructure

[cc creator]Comparison not working

I have an array of Nodes 'flags', and I want to set my object's position at the first object in that array, it works and the object actually gets positioned as intended, but when I make the comparison it fails and logs 'NO'.
The line of code that sets the position works, but the comparison fails, what's wrong here?!
start: function () {
this.node.position = this.flags[0].position;
this.movement();
},
movement: function() {
if (this.node.position == this.flags[0].position) { // Problem
console.log("YES");
}
else {
console.log("No");
Update:
When I do it like this it works:
if (this.node.position.x == this.flags[0].position.x) // or position.y
Well if you write javascript here (and it looks like you do) there're two things you should know:
You can't compare objects with == out of the box
({"a":1} == {"a":1})
Will return false (you may try it yourself in your browser.
As a workaround you could do something like:
function posCompare(p1, p2){
return p1.x === p2.x && p1.y === p2.y;
}
Then use it instead of == for positions
See how I use === instead of ==? Second thing to know is Use only ===. You can learn the difference Which equals operator (== vs ===) should be used in JavaScript comparisons? but I'd keep away from == anywhere. It's slower, it may cause strange errors here and there - just don't use it at all

Avoiding data corruption if column state is saved, new column is defined in server and data is saved in edit

Answer in
How to replace remapColums with remapColumnsByName in free jqgrid
contains code to save and restore jqgrid column order.
It contains method to restore columns state:
var restoreColumnState = function (colModel) {
var colItem, i, l = colModel.length, colStates, cmName,
columnsState = getObjectFromLocalStorage(myColumnStateName);
if (columnsState) {
colStates = columnsState.colStates;
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") {
colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]);
}
}
}
return columnsState;
};
This method causes invalid data posting from inline edit if new column is defined in server side.
jqgrid is populated from remote json data array. In this array columns must be the same as in column state.
If columns state is saved and new column is added to jqgrid in server code,
colStates[cmName] value is undefined.
This code causes new column to be added to end of jqgrid columns. However, in json data array it appears in the column as defined in server.
On inline edit, if row is saved, wrong values are assigned to form fields and invalid values are passed to server.
I tried to fix it adding colStates[cmName] !== undefined check:
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid" && colStates[cmName] !== undefined) {
but problem persists.
How to fix this that if new column is added to jqgrid colmodel in server, restoring column state allows to save correct data?
New column which is not found in saved columns list should appear in the same relative position as it is defined in colmodel. Column order shoudl corrspond to remote data from server.
Update
ColModel is defined in Razor view in variable cm
<script>
var
$grid,
myColumnsState,
isColState,
myColumnStateName;
$(function () {
var cm= #Html.Raw(Model.GetColModel());
$grid = $("#grid");
myColumnStateName = #Model.ColumnStateName();
myColumnsState = restoreColumnState(cm, myColumnStateName);
isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null;
$grid.jqGrid({
page: isColState ? myColumnsState.page : 1,
sortname: isColState ? myColumnsState.sortname : "",
sortorder: isColState ? myColumnsState.sortorder : "",
....
</script>
I know the problem very good! One need to implement some kind of validating checks of the previously saved state of the grid before the usage. The deepness of checks could depend on the exact requirements of your application and from the information which one knows exactly. The most opened and unclear thing: should one make some correction/fixing of the previously saved state or should one discard the state on the first small error? The answer on the question depends on the project where jqGrid are used. Deep fixing could include fixing of sorting parameter and modifying previously saved filter. Another example: the state could include ids of selected rows, but the fixing of the part of the state could be bad idea in the common case. One loading of the data could imply one setting of selected rows, but loading of another data (unfiltered for example) could do have the rows and the rows should be do selected. There are no best choice in the case, all depends on the exact project requirements. In any way the implementation of the state validation/fixing isn't a simple code.
Only because of the complexity of the problems of validation of previously saved state and the existence of different scenarios of validation I didn't implemented such feature in free jqGrid. Any good implementation needs time and the resulting code will be not simple. It will have some options for some typical scenarios. I would like to implement the feature in the future, but I just didn't found the time for the implementation, because I have to do my main job to earn money for my family and I still try to help other people in the community who have small, but important, for the person, problems with jqGrid of free jqGrid.