React native concatenate instead of sum - firebase

I am creating an app using React Native and Firebase. Sample data from firebase is as below.
Sample Data (Firebase)
accountName:"Frimi"
accountType:"debit"
createdAt:March 24, 2020 at 7:05:56 PM UTC+5:30
initialAmount:2000
userId:"t7DJ##################"
username:"de#####"
From this data's I need to get the total amount of the initialAmount from several data's. I do this in react native as follows
Fetch Total (React Native)
fetchTotalAmount = () => {
const { accounts } = this.props
const uid = firebase.auth().currentUser.uid
return accounts && accounts.map((account) => {
let total = 0
return account.userId == uid ?
total += account.initialAmount : null
})
}
The problem here is instead of adding values I am getting concatenated string. I need to get sum of the initialAmount.

Try casting account.initialAmount to a Number like:
total += Number(account.initialAmount) : null
Look at this post for more casting references.

Related

Extracting sql data in ionic 5 without getting a ZoneAwarePromise

Using the ionic 5 framework I am trying to extract data from my SQLite database using a function:
getGlobal(name, db) {
console.log('... getting global');
var result;
sqlQuery = 'SELECT `value` FROM globals WHERE `name` = "' + name + '"';
console.log('sql query: ' + sqlQuery);
result = db.executeSql(sqlQuery, []).then(value => {
return JSON.parse(value.rows.item(0).value);
});
console.log('return: ', result);
return result;
}
I have tried even further ".then(data => {})" chaining to extract the correct result but withoug success. Always produces a ZoneAwarePromise.
Not sure where I am going wrong
The problem is not with the function itslef. Even converting it to an async function with await will return a fullfilled promise.
At the receiving end, eg
getGlobal('variable', db)
extract the value by adding
.then(value => console.log(value));
This is me learning more about promises. Maybe this answer is helpful to others.

Firebase Cloud function: Weird timestamp bug

So I have implemented Stories in my Flutter+Firebase app, and wrote a Cloud Function in JS to delete all stories older than 24h. I added a test Story in the Database, with a field 'timestamp' and set it to August 25, 8:00. Now when I am running the function, I print out the document id and the timestamp of that found document. However, the dates that get printed out are all in 1973!?
Here is my function:
// Start delete old Stories
const runtimeOpts = {
timeoutSeconds: 300,
memory: '512MB'
}
const MAX_CONCURRENT = 3;
const PromisePool = promisePool.PromisePool;
exports.storiesCleanup = functions.runWith(runtimeOpts).pubsub.schedule('every 1 minutes').onRun(
async context => {
console.log('Cleaning stories...');
await getOldStories();
//const promisePool = new PromisePool(() => deleteOldStories(oldStories), MAX_CONCURRENT);
//await promisePool.start();
console.log("finished cleaning stories");
}
);
async function getOldStories() {
const yesterday = Date.now() - 24*60*60*1000;
console.log("Yesterday: " + yesterday);
var storyPostsRef = admin.firestore().collection("StoryPosts");
var query = storyPostsRef.where("timestamp", "<", yesterday);
storyPostsRef.get().then(
querySnapshot => {
querySnapshot.forEach(
(doc) => {
// HERE I AM PRINTING OUT!
console.log("Found document: " + doc.id + ", which was created on: " + doc.data().timestamp);
//doc.ref.delete();
}
)
return null;
}
).catch(error => {throw error;});
}
//End delete old stories
Here is a picture of a document and its timestamp:
And this is a picture of the id and timestamp printed out for that document:
Edit: So for printing out, I figured that if I print doc.data().timestamp.seconds I get the correct number of seconds since epoch. But I still don't understand what the number 06373393200.000000 (printed in the picture above) is. And how do I then make a query when I want to get all stories where the timestamp is small than today-24h ?
var query = storyPostsRef.where("timestamp", "<", Timesstamp.fromDate(yesterday)); does not work.
If you come to the conclusion that the printed timestamp is from a year other than the one shown in the console, then you are misinterpreting the output. Firestore timestamps are represented with two values - an offset in seconds since the unix epoch, and another offset in nanoseconds from that time. This much is evident from the API documentation for Timestamp.
You're probably taking the seconds offset value and interpreting as an offset in milliseconds, which is common in other timestamp systems. You can see how this would cause problems. If you want to take that a Firestore offset in seconds and use a tool to interpret it in a system that uses milliseconds, you will need to first multiply that value by 1,000,000 to convert seconds to milliseconds.

Indexing data in my firebase realtime database rules based on the nested value

I have the following JSON tree from my realtime database:
{
"old_characters" :
{
"Reptile" : {
"kick" : 20,
"punch" : 15
},
"Scorpion" : {
"kick" : 15,
"punch" : 10
},
"Sub-zero" : {
"kick" : 30,
"punch" : 10
}
},
"new_characters" : {
//...ect
}
}
Is it possible to set rules in my firebase console so that I can index my data based on the character with the highest value of kick?
The constraints are:
- character_name are dynamic.
- Key "kick" is static, but its value is dynamic.
Result should be:
Sub-zero first (kick 30)
Reptile second (kick 20)
Scorpion third (kick 15)
What you want seems to be a fairly simple Firebase query on the kick property:
var ref = firebase.dababase().ref('old_characters');
var query = ref.orderByChild('kick');
query.once(function(snapshot) {
snapshot.forEach(function(characterSnapshot) {
console.log(characterSnapshot.key);
console.log(characterSnapshot.child('kick').val());
});
});
You'll note that this prints the results in ascending order. You can:
either reverse the results client-side
or add an inverted property with -1 * score to each character and then order on that
To learn more about the inverting/sorting descending, have a look at some of these previous questions:
firebase -> date order reverse
Sorting in descending order in Firebase database
sorting numbers with firebase

How to separate multiple columns from a range in an array?

I have a range of data in a Google Sheet and I want to store that data into an array using the app script. At the moment I can bring in the data easily enough and put it into an array with this code:
var sheetData = sheet.getSheetByName('Fruit').getRange('A1:C2').getValues()
However, this puts each row into an array. For example, [[Apple,Red,Round],[Banana,Yellow,Long]].
How can I arrange the array by columns so it would look: [[Apple,Banana],[Red,Yellow],[Round,Long]].
Thanks.
It looks like you have to transpose the array. You can create a function
function transpose(data) {
return (data[0] || []).map (function (col , colIndex) {
return data.map (function (row) {
return row[colIndex];
});
});
}
and then pass the values obtained by .getValues() to that function..
var sheetData = transpose(sheet.getSheetByName('Fruit').getRange('A1:C2').getValues())
and check the log. See if that works for you?
Use the Google Sheets API, which allows you to specify the primary dimension of the response. To do so, first you must enable the API and the advanced service
To acquire values most efficiently, use the spreadsheets.values endpoints, either get or batchGet as appropriate. You are able to supply optional arguments to both calls, and one of which controls the orientation of the response:
const wb = SpreadsheetApp.getActive();
const valService = Sheets.Spreadsheets.Values;
const asColumn2D = { majorDimension: SpreadsheetApp.Dimension.COLUMNS };
const asRow2D = { majorDimension: SpreadsheetApp.Dimension.ROWS }; // this is the default
var sheet = wb.getSheetByName("some name");
var rgPrefix = "'" + sheet.getName() + "'!";
// spreadsheetId, range string, {optional arguments}
var single = valService.get(wb.getId(), rgPrefix + "A1:C30");
var singleAsCols = valService.get(wb.getId(), rgPrefix + "A1:C30", asColumn2D);
// spreadsheetId, {other arguments}
var batchAsCols = valService.batchGet(wb.getId(), {
ranges: [
rgPrefix + "A1:C30",
rgPrefix + "J8",
...
],
majorDimension: SpreadsheetApp.Dimension.COLUMNS
});
console.log({rowResp: single, colResp: singleAsCols, batchResponse: batchAsCols});
The reply will either be a ValueRange (using get) or an object wrapping several ValueRanges (if using batchGet). You can access the data (if any was present) at the ValueRange's values property. Note that trailing blanks are omitted.
You can find more information in the Sheets API documentation, and other relevant Stack Overflow questions such as this one.

Can't get data when passing two parameters on SQLite in React Native

I tried to pass two parametes like below for select query but I am no getting the data
db.transaction(tx => {
tx.executeSql('SELECT * FROM data WHERE (month = ? AND items_id = ?);', ["Sep 2018",68], (_, { rows }) => {
console.log(JSON.stringify(rows));
});
});
OutPut :
{"_array":[],"length":0}
But is passed the value in query I got the out put like below
db.transaction(tx => {
tx.executeSql('SELECT * FROM data WHERE (month = "Sep 2018" AND items_id = 68);', [], (_, { rows }) => {
console.log(JSON.stringify(rows));
});
});
Output :
{"_array":[{"item_id":"68","item_name":"Apple","month":"Sep 2018"}],"length":1}
Note :
I am using Expo Sqlite ("expo": "^27.0.1",)
import Expo, { SQLite } from 'expo';
const db = SQLite.openDatabase('itemsDb.db');
Kindly help to achieve this. Thanks!
It may have the same bug as in react-native-sqlite-storage:
The parameters are converted from numbers into strings making the query expression to fail, as the items_id column contain integers
One solution is to cast the value back to integer in the SQL command:
SELECT * FROM data WHERE (month = ? AND items_id = cast(? as integer))
The original bug is reported here

Resources