I use POST /sapi/v1/capital/withdraw/apply to withdraw cryptos from Binance. It returns an ID. I immediately call GET /sapi/v1/capital/withdraw/history. The weird thing is it sometimes doesn't contain the ID I just got.
Below is my typescript code:
const startTime = Date.now();
const response = await callWithdrawApi(coin, network, amount, address);
const id = response.id;
const endTime = null; // Default: present timestamp, as stated in official document.
const details = await callWithdrawHistoryApi(startTime, endTime);
details should contain a withdraw with the ID I just got. It sometimes does, but most of the time it is empty. I assume this is because Binance haven't put that withdraw into database yet. But then how do I get the withdraw detail after performing withdraw?
I can wait for 1 or 2 seconds sure, but that is not a good solution. 99.99% of the time it will be unnecessary waiting, and 0.01% of the time it will still not be in the database, because there is no guarantee how long it would take.
Related
I observed a huge amount of read on my firebase console and I was wondering if this might come from my "referral function".
This function works perfectly fine but I was wondering whether or not this function could end up with a crazy load of read in case of app scaling.
My question: does this function imply that every time a user comes in, it will account for a number of read equivalent to the number of users in my collection ?
Thus, as this function is an onUpdate, will it redo the job every time a document is updated ?
I would not mind some resources on the topic because I found it unclear on Firebase's website.
I hope my questions are clear!
Thank you very much!
export const onReferralInfoUpdate = functions.
firestore.document('users/{userUid}')
.onUpdate(async (change, context) => {
const before = change.before.data();
const after = change.after.data();
const currentUserUid = after["uid"];
if (before.godfather_code == after.godfather_code){
console.log('Text did not change')
return null
}
const godfatherUserSnapshot = await db.collection('users').where("referral_code", "==", after.godfather_code).get();
const godfather = godfatherUserSnapshot.docs[0].data();
const godfatherUid = godfather["uid"];
const userRef = db.collection('users').doc(after.uid);
const godfather_code = after.godfather_code
await userRef.update({godfather_code})
console.log(`the text before was >> ${before.godfather_code} << and after is ${after.godfather_code}` )
let batch = db.batch();
const updateGodfather = db.collection('users').doc(godfatherUid);
batch.update(updateGodfather, {
reward: admin.firestore.FieldValue.increment(100),
godChildUid: admin.firestore.FieldValue.arrayUnion(currentUserUid),
});
return batch.commit();
});
Yes, the where("referral_code", "==", after.godfather_code).get() will fetch all the documents matching the query every time onUpdate() function triggers and you'll be charged N reads (N = number of matched documents). The Admin SDK doesn't have any caching like Client SDKs.
Does this function imply that every time a user comes in, it will account for a number of read equivalent to the number of users in my collection ?
Not numbers of documents in the users collection, only the documents matching your query as mentioned.
I'm making a Firebase function, that is supposed to get the value of a field in the Realtime Database, write the value in a Firestore Document and increment the original field. The problem is when the function gets called very frequently e.g. 500 times a second, it gets and writes the same value in a lot of documents, because many executions will get the same value before it gets incremented. Is there any way to get the value of a Realtime DB field and increment it at the same time or somehow prevent this issue?
Thank you in advance.
My code:
const { getFirestore } = require('firebase-admin/firestore');
const { getDatabase, ServerValue } = require('firebase-admin/database');
const rb = getDatabase();
const db = getFirestore();
exports.increment = functions.https.onCall(async (data, context) => {
rb.ref('count').get().then((snapshot)=>{
let value = snapshot.val();
db.collection("documents").doc(value.toString()).set({count:value});
rb.ref("count").set(ServerValue.increment(1))
})
});
Since you're using an auto-scaling infrastructure with Cloud Functions, it will spin up new instances if there are a lot of requests coming in. If you don't want to do that, it might be worth setting a maximum number of instances on your Cloud Function.
I'm using Stripe and am trying to implement the scenario described here
The frontend is making a call to the backend that has this code
var service = new PaymentIntentService();
var createOptions = new PaymentIntentCreateOptions
{
PaymentMethodTypes = new List<string>
{
"card",
},
Amount = (long?)(payment.Amount * 100),
Currency = "EUR"
};
var result = await service.CreateAsync(createOptions);
return result.ClientSecret
In the documentation it says that the below code should be run "later" but it doesn't specify when. In my case I would prefer submitting the transfers to Stripe as soon as possible and preferably connecting them to the above payment so the transfers would be automatically handled by Stripe when the payment is done.
As I read the documentation (https://stripe.com/docs/api/transfers/create#create_transfer-source_transaction) SourceTransaction could be used for this.
var transferService = new TransferService();
var transfer1Options = new TransferCreateOptions
{
Amount = 100,
Currency = "eur",
Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
SourceTransaction = result.Id
};
var transfer1 = transferService.Create(transfer1Options);
The result -variable contains a Charges -list but that is empty and when doing the above, i.e. adding the payment intent's id to SourceTransaction property, I get an error that the charge does not exist.
In the documentation it says that the below code should be run "later" but it doesn't specify when
It's whenever you are ready to make the transfer, after the payment has succeeded, essentially.
As I read the documentation (https://stripe.com/docs/api/transfers/create#create_transfer-source_transaction) SourceTransaction could be used for this.
Yep, you should definitely use source_transaction here! Otherwise the transfers won't succeed since the funds would not be available yet.
The result -variable contains a Charges -list but that is empty and when doing the above, i.e. adding the payment intent's id to SourceTransaction property, I get an error that the charge does not exist.
The value to pass to source_transaction is indeed the intent.charges.data[0].id , of a PaymentIntent that has succeeded and has a Charge.
You don't have a Charge ID because you haven't actually processed a payment yet. Creating a PaymentIntent doesn't process a payment.
You have to do the normal full PaymentIntent integration by building a form that collects payment details and 'confirms' the PaymentIntent, that's the action that processes the payment, and after that succeeds, the charges array will have a Charge in it that can be used for the transfer. For example you might create the transfer as part of handling the payment_intent.payment_succeeded webhook event.
https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements
I am using React and Stripe payments for subscriptions. I have the checkout all set using Elements. I want to add the possibility for a user to add a promo code set up in stripe that will be added to the subscription on creation.
What i want to do is check that the promo code is valid (after checking the various subscriptions on the code) and show the affect to the customer before they commit to subscribe. I thought there would have been something built into the API but apparently not. And Stripe support desk (which is generally very good) don't don't seem to know why i want to check a code is valid and show customer it is before they actually click subscribe.
const promotionCodes = await stripe.promotionCodes.list({
active: true,
code: promoCode,
});
if (promotionCodes.data.length > 0) {
const today = Math.floor(Date.now() / 1000);
const expiry =
promotionCodes.data[0].expires_at ||
Math.floor(Date.now() / 1000) + 20;
if (today <= expiry) {
valid = true;
}
}
This is retrieving the code (there can only be 1 active result so it gets it fine). I then check its not expired. All fine, the data I cannot get is if the Coupon the Promotion code is attached to, is restricted to only certain products. For example, if i chose gold plan and try to use a code for silver plan then it would be invalid.
I'm implementing Stripe into my app, however, I want to generate the fee amount via server side as this can allow me to update as and when. I've tried to have a go, but to no luck.
exports.calculateFees = functions.https.onRequest((req, res) => {
var total = req.body
var percentageFeeCharge = 10
var feeAmount = 0
feeAmount = ((percentageFeeCharge/ 100) * total))
return res.send(feeAmount)
});
I can pass in the total from my app to the function which is cool, however, I need the amount to be generate with no decimals or symbols as Stripe deals with pennies i.e. £1.00 would equate to 100 etc.
I believe the res() is the response which is what I need to get the amount back, I believe so? I'm new to NodeJS so this may be simple, but I am struggling.