How to get all event logs of the contract in tron network using tronweb in node js without any limit? - tron

How to get all events logs of the contract in tron network using tronweb in node js without any limit? or is there need of any middle ware storage like redis, etc?
Need to get all data at once before loading dapp home page. The dApp is made in react js. And Trongrid api have this limit of 200 records in single request.

You can use fingerprint (it works like continue token)
async getContractTransferEventsByUser(eventName, userId) {
let result = [];
let tronGrid = new TronGrid(this.tronWeb);
try {
let continueToken = '';
while (true) {
let res = await tronGrid.contract.getEvents(YOUR_CONTRACT_ADDRESS, {
only_confirmed: true,
event_name: eventName,
limit: 200,
fingerprint: continueToken,
order_by: "timestamp,asc",
min_timestamp: minTime, //remove if you don't need it
filters: { id: userId.toString() } //if you need to filter events by one or more values, for example, by user id (if this information is presented in event log), remove if you don't need it.
});
if (!res.success) {
console.warn("Can't get events for the contract");
break;
}
result = result.concat(res.data);
if (typeof res.meta.fingerprint !== 'undefined') {
continueToken = res.meta.fingerprint;
} else {
break;
}
}
} catch (error) {
console.error(error);
} finally {
return result;
}
},

Related

How to make pagination work? Async await function in vue.js 3 setup

I was trying to make an app which lists a user's repositories from github using github API, however I'm having a big problem with fetching data from all pages (so far I can only get repos from one page). I tried to fix it by using an async/await function (instead of Promise), but it's also my first time using vue3 and I have no idea how to have a function inside of the setup() method.
The current code is here:
https://github.com/agzpie/user_repos
My try at using async/await, which didn't work:
import ListElement from "./components/ListElement";
import { ref, reactive, toRefs, watchEffect, computed } from "vue";
export default {
name: "App",
components: {
ListElement,
},
setup() {
const name = ref(null);
const userName = ref(null);
const state = reactive({ data: [] });
let success = ref(null);
const userNameValidator = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i;
const split1 = reactive({ spl1: [] });
const split2 = reactive({ spl2: [] });
async function myFetch() {};
/*
* Check for input in the form and then fetch data
*/
watchEffect(() => {
if (!userName.value) return;
if (!userNameValidator.test(userName.value)) {
console.log("Username has invalid characters");
return;
}
let hasNext = false;
state.data = [];
do {
async function myFetch() {
let url = `https://api.github.com/users/${userName.value}/repos?per_page=5`;
let response = await fetch(url);
if (!response.ok) {
success.value = false;
throw new Error(`HTTP error! status: ${response.status}`);
}
success.value = true;
// check response.headers for Link to get next page url
split1.spl1 = response.headers.get("Link").split(",");
let j = 0;
while (j < split1.spl1.length) {
split2.spl2[j] = split1.spl1[j].split(";");
console.log(split2.spl2[j][0]);
console.log(split2.spl2[j][1]);
if (split2.spl2[j][1].includes("next")) {
let urlNext = split2.spl2[j][0].replace(/[<>(\s)*]/g, "");
console.log(urlNext);
url = urlNext;
hasNext = true;
break;
} else {
hasNext = false;
}
j++;
}
// second .then
let myData = await response.json();
state.data.push(...myData);
console.log("data", myData);
name.value = "";
}
myFetch().catch((err) => {
if (err.status == 404) {
console.log("User not found");
} else {
console.log(err.message);
console.log("oh no (internet probably)!");
}
});
} while (hasNext);
});
// Sort list by star count
const orderedList = computed(() => {
if (state.data == 0) {
return [];
}
return [...state.data].sort((a, b) => {
return a.stargazers_count < b.stargazers_count ? 1 : -1;
});
});
return {
myFetch,
success,
isActive: true,
name,
userName,
ListElement,
...toRefs(state),
orderedList,
};
},
};
Any help would be highly appreciated
The call to myFetch() near the end is a call to an async function without an await, so it is effectively going to loop (if hasNext was initialized to true, but it isn't) without waiting for it to complete.
You should probably change that line to await myFetch() and wrap it all with a try/catch block.
I also don't really care for the way you're directly updating state inside the async myFetch call (it could also be doing several of those if it looped) and perhaps it should be returning the data from myFetch instead, and then you can use let result = await myFetch() and then make use of that when it returns.
Also, instead of awaiting myFetch() result, you could not await it but push it onto a requests array and then use await Promise.all(requests) outside the loop and it is one operation to await, all requests running in parallel. In fact, it should probably be await Promise.allSettled(requests) in case one of them fails. See allSettled for more.
But also I wonder why you're reading it paged if the goal is to fetch them all anyway? To reduce load on the server? If that is true, issuing them paged but in parallel would probably increase the load since it will still read and return all the data but require multiple calls.

Axios cancelToken cancel and delete while sending multi requests strange behavior

I'm using axios cancelToken in order to cancel requests made by the user in order to not overload the api. But for some reason I'm struggling to understand why it works only for odd number of requests and if the object of the remains with a reference. In the following code I'm experiencing glitches, it misses most of the requests.
some of the functions are mutations some actions
async add({ dispatch, commit, state }, { item }) {
addLoader({id:item.id});
let { data } = await this.$axios.get("/add", {
params: item,
cancelToken: state.loaders[item.id].token,
});
//commit adding the item
},
// every token is being created here
function createToken(id = null) {
let cancelToken = null;
cancelToken = this.$axios.CancelToken.source();
return cancelToken;
}
addLoader(state, { id }) {
if (state.loaders[id]) {
state.loaders[id].cancel();
}
state.loaders = {
...state.loaders,
[id]: createToken.call(this),
};
},
removeLoader(state, { id }) {
let loadersObj;
let loader;
if (state.loaders[id]) {
loadersObj = { ...state.loaders };
loaders[id].cancel();
delete loaders[id];
// cannot delete before keeping a reference for some reason
// loader = loadersObj[id];
// loader.cancel();
// delete loadersObj[id];
////////////////////////
state.loaders = loadersObj;
} else {
console.log("didnt find any loader", id);
}
},
So basically if I'm using the code that i've marked it works perfectly for odd number of requets:
request1 - canceled
request2 - canceled
request3 - passed
when in even number of requests:
request1 - canceled
request2 - canceled
Appreciate it if you can guide me through to understand exactly what am I missing.
Thanks.

React Native Firebase push notification

I have a requirement to automatically send push notifications to my application when new data is inserted into firebase.
Is there any way to do so ?
Thanks !
You can use Firebase Functions as a middleware function for sending push notifications via FCM to the device If the database value is changed.
Adding an example from my FirebaseDBtoFCMFunction repo.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendPushNotification = functions.database
.ref('/users/{user_id}') // Put your path here with the params.
.onWrite(async (change, context) => {
try {
const { after } = change;
const { _data } = after;
const { deviceToken } = _data.receiver; // Always send the device token within the data entry.
if(!deviceToken) return;
const payload = {
notification: {
title: 'Notification',
body: `FCM notification triggered!`
},
data: context.params // Passing the path params along with the notification to the device. [optional]
};
return await admin.messaging().sendToDevice(deviceToken, payload);
} catch (ex) {
return console.error('Error:', ex.toString());
}
});
Inside your application add child_change (valueChanged) or child_add event for specific database location than when it changes, it will fired.
From doc.
FirebaseDatabase.DefaultInstance
.GetReference("Leaders").OrderByChild("score")
.ValueChanged += HandleValueChanged;
}
void HandleValueChanged(object sender, ValueChangedEventArgs args) {
if (args.DatabaseError != null) {
Debug.LogError(args.DatabaseError.Message);
return;
}
// Do something with the data in args.Snapshot
}
For nodejs value listener

Loop expo biometric authentication until success

I'm trying to implement a biometric authentication (faceID / fingerprint) on Android using React-native with Expo.
Using the LocalAuthentication.authenticateAsync() function, the user is able to authenticate with his biometry. But if it fail, the user have to press the biometric authentication again.
So i tried a little trick with a recursif or do while loop but the result is strange :
const scanFingerPrint = async () => {
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
} catch (e) {
console.log(e);
}
};
With this code, if the user fail the biometric authentication, it will pass in the "else" infinitly...
So I was wondering how to handle that on android.
You can handle it manually using a variable.
First create variable retryCount inside constructor or as a property of class so that it is accessible in each function.
constructor(props) {
super(props);
this.retryCount = 3;
}
set the value of retryCount before calling scanFingerPrint function.
this.retryCount = 3; //number of attempts you want to provide
Now modify function like below to prevent infinite loop:
const scanFingerPrint = async () => {
try {
if (this.retryCount <= 0){
//exceeded the number of attempts..try again after a minute
} else{
this.retryCount--;
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
}
} catch (e) {
console.log(e);
}
};
You can pass function variable for attempts.
see this,
const scanFingerPrint = async (remainingAttempts = 5) => { // you can change 5 as per your choice
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential().then(credentials =>
onScan(credentials)
);
} else {
ShakeAnimation(animatedValueModal);
if (remainingAttempts) {
remainingAttempts--;
scanFingerPrint(remainingAttempts);
} else {
alert("You have exceeded max scan limit.");
}
}
} catch (e) {
console.log(e);
}
};
and you do not need to change anything else. not event your first time function call.
Expo provide an "error" key on the results of the local authentication. To not handle an hardware error i used this :
if (!results.success) {
switch (results.error) {
case "lockout":
setLocked(true);
break;
case "authentication_failed" || "too_fast":
ShakeAnimation(animatedValueModal);
await scanBiometric();
break;
case "user_cancel" :
break;
default:
ShakeAnimation(animatedValueModal);
break;
}
}

I have created a chat application in which every ten second it takes records from database but i want to show notification at taskbar

I want to show new message notification at taskbar in asp.net MVC or in somewhere to aware user that new message have came.
You can add one Boolean column in you table namely "Seen" with default false value. when user open that message then update that value as true. so you will be easily able get not seen messages for notification. and you can show notification at the top of the page in header section.
We can show desktop notification by javascript function
function createNotification() {
var options = {
body: 'This is the body of the notification',
icon: 'stupidcodes.com.png',
dir: 'ltr'
};
var notification = new Notification("Hi there", options);
notification.onclick = function () {
window.open(document.URL);
};
}
function notifyMe() {
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
}
else if (Notification.permission === "granted") {
createNotification();
}
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function (permission) {
if (!('permission' in Notification)) {
Notification.permission = permission;
}
if (permission === 'granted') {
createNotification();
}
});
}
}
first check throgh ajax function if there is any unread funtion then call this notifyMe() function