Twitter4j Getting Tweets Too Long - database

Hello i have tweet id's and i saved them to database before. But i saw that i could not save created time efficiently (it is saved like 00:00:00). Therefore i wished to update my tweets with tweet id by using following code.
MyConnectionBuilder myConnection = new MyConnectionBuilder();
Twitter twitter = new TwitterFactory(myConnection.configuration.build()).getInstance();
Status status = twitter.showStatus(Long.parseLong(tweetId));
But it takes too much time to get tweets, is there any rate limit for this ? If there is a rate limit how can i make it faster ?

Updating every single tweet via showStatus wastes your "credits" for a given timeframe (rate-limit).
For updating multiple tweets, you should use lookup with a maximum of 100 ids per request. This call will use the /statuses/lookup endpoint.
Rate-Limit and endpoint documentation can be found here
Code-Snipped for it:
Twitter twitter = twitterFactory.getInstance();
ResponseList<Status> responseList = twitter.lookup(ArrayUtils.toPrimitive(ids));
if(responseList != null) {
for (Status status : responseList) {
// do what you need to do here
}
}

Related

Chunking a large GraphQL request into smaller requests

I'm using Apollo React Native client working with a query for which my request body has become too large to use (it's being rejected by our CDN for a request-too-large rule). So, I'm hoping to split/chunk this request into smaller requests and particularly curious if it's possible to do parallelized.
I think this is better illustrated with an example, so we can imagine I'm building a WhatsApp challenger -- WhoseApp -- for which we want users to be able to see who of their contacts have a WhoseApp account upon signup.
For our implementation, we'll take all of the phone numbers stored on our user's device and send them to our GraphQL query GetPhoneNumberAccountStatus which accepts an array of phone numbers and which returns an Account for each number associated to an account (and nothing for those that are not).
If we send the contacts as one request, we'll have a request body that looks something like this:
[
"+15558675309",
"+15558675308",
"+15558675307"
"+15558675306"
...
// 500+ numbers for some users
]
What's the correct way to split this request into multiple?
I'm curious of both:
What's the 'optimal' way to approach this using a sequential approach (e.g., send one group, wait for response, send next group), or
Is there a way to do this parallelized (e.g., send all groups at beginning and then receive responses as they arrive)?
I initially figured it might be possible to use useLazyQuery and send tranches of ~50 numbers at a time, firing each group and then awaiting the responses but this GitHub thread for the library makes it clear that that's not the correct approach.
I think it's readable
const promises = [];
const chunkSize = 50;
for (let i = 0; i <= contacts.length; i += chunkSize) {
const promise = apollo.query({...dataHere});
promises.push(promise);
}
await Promise.all(promises);

Firebase GET request orderby 400 bad request

For a get request, I am trying to user order by like below but always get a 400 bad request. Here, multiple users can have multiple blog posts each with a unique id like b1 in screenshot below. The long sequence of characters is the uid of a user under blogs. Each user has their own uid.
https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app/blogs.json?orderBy="createdAt"
I followed the documentation here
https://firebase.google.com/docs/database/rest/retrieve-data
All I am doing is issuing a simple GET request in react js as follows:
const resp = await fetch(`https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app/blogs.json?orderBy="createdAt"``)
const data = await resp.json()
if(!resp.ok) { ... }
Below is the database single entry for schema reference
As I said in my previous comment, this URL is invalid:
https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app/blogs.json/orderBy="createdAt"
                                                                                     ^
The query portion of a URL starts with a ? character.
https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app/blogs.json?orderBy="createdAt"
                                                                                     ^
Firebase Realtime Database - Adding query to Axios GET request?
I followed the above similar issue resolution to solve my problem

Journey builder's custom activity: Fetch data extension data in bulk

I am new to Salesforce Marketing Cloud and journey builder.
https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/creating-activities.html
We are building journey builder's custom activity in which it will use a data extension as the source and when the journey builder is invoked, it will fetch a row and send this data to our company's internal endpoint. The team got that part working. We are using the postmonger.js.
I have a couple of questions:
Is there a way to retrieve the data from data extension in bulk so that we can call our company's internal bulk endpoint? Calling the endpoint for each record in the data extension for our use case would not be efficient enough and won't work.
When the journey is invoked and an entry in the data extension is retrieved and that data is sent to our internal endpoint, is there a machanism to mark this entry as already sent such that next time the journey is run, it won't process the entry that's already sent?
Here is a snippet of our customActivity.js in which this is populating one record. (I changed some variable names.). Is there a way to populate multiple records such that when "execute" is called, it is passing a list of payloads as input to our internal endpoint.
function save() {
try {
var TemplateNameValue = $('#TemplateName').val();
var TemplateIDValue = $('#TemplateID').val();
let auth = "{{Contact.Attribute.Authorization.Value}}"
payload['arguments'].execute.inArguments = [{
"vendorTemplateId": TemplateIDValue,
"field1": "{{Contact.Attribute.DD.field1}}",
"eventType": TemplateNameValue,
"field2": "{{Contact.Attribute.DD.field2}}",
"field3": "{{Contact.Attribute.DD.field3}}",
"field4": "{{Contact.Attribute.DD.field4}}",
"field5": "{{Contact.Attribute.DD.field5}}",
"field6": "{{Contact.Attribute.DD.field6}}",
"field7": "{{Contact.Attribute.DD.field7}}",
"messageMetadata" : {}
}];
payload['arguments'].execute.headers = `{"Authorization":"${auth}"}`;
payload['configurationArguments'].stop.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].validate.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].publish.headers = `{"Authorization":"default"}`;
payload['configurationArguments'].save.headers = `{"Authorization":"default"}`;
payload['metaData'].isConfigured = true;
console.log(payload);
connection.trigger('updateActivity', payload);
} catch(err) {
document.getElementById("error").style.display = "block";
document.getElementById("error").innerHtml = err;
}
console.log("Template Name: " + JSON.stringify(TemplateNameValue));
console.log("Template ID: " + JSON.stringify(TemplateIDValue));
}
});
Any advise or idea is highly appreciated!
Thank you.
Grace
Firstly, i implore you to not proceed with the design pattern of fetching data for each subscriber, from Marketing Cloud, that gets sent through the custom activity, for arguments sake i'll list two big issues.
You have no way of limiting the configuration of data extensions columns or column names in SFMC (Salesforce Marketing Cloud). If any malicious user or by human error would delete a column or change a column name your service would stop receiving that value.
Secondly, Marketing Cloud has 2 sets of API limitations, yearly and minute by minute. Depending on your licensing, you could run into the yearly limit.
The problem you have with limitation on minutes (2500 for REST and 2000 for SOAP) is that each usage of the custom activity in journey builder would multiple the amount of invocations per minute. Hitting this limit would cause issues for incremental data flows into SFMC.
I'd also suggest not retrieving any data from Marketing Cloud when a customer gets sent through a custom activity. Users should pick which corresponding rows/data that should be sent to the custom activity in their segmentation.
The eventDefinitionKey can be picked up from postmonger after requestedTriggerEventDefinition in the eventDefinitionModel function. eventDefinitionKey can then be used to programmatically populate SFMC's POST call with data from the Journey Data model, thus allowing marketers to select what data to be sent with the subscriber.
Following is some code to show how it would work in your customActivity.js
connection.on(
'requestedTriggerEventDefinition',
function (eventDefinitionModel) {
var eventKey = eventDefinitionModel['eventDefinitionKey'];
save(eventKey);
}
);
function save(eventKey) {
// subscriberKey fetched directly from Contact model
// columnName is populated from the Journey Data model
var params = {
subscriberKey: '{{Contact.key}}',
columnName: '{{Event.' + eventKey + '.columnName}}',
};
payload['arguments'].execute.inArguments = [params];
}

Fetching data really fast from Google cloud firestore

I am making a flutter application and I’m using cloud firestore as my online database. One of the features in my app is looking for nearby users and showing their profile to the current user in a custom widget on screen. The way I do it is I get current user’s location (either live location or the address saved in database) and then go through every single user in my database collection for users. I get the address of the user from the stored data, calculate the distance using Distance Matrix API and then if distance is less than a specific number (e.g 10000 meter) I create the profile widget for the user to show it on screen.
There are 2 problems:
1- if my number of users grows (for example a million users), By going through every user detail and calculating the distance, It can take a really long time to get the results on the screen . Right now, I only have 20 users for testing purposes and when I search for nearby users, it can take 30 seconds for the results to show up on the screen.
2- With a slow internet connection, the waiting time can be much much more and it can use lots of user’s data for this simple task.
How can I improve this feature and make it faster?
(The current idea that I have is dividing user’s in different documents with respect to their location and then going through only one of the documents by using current user’s location. The problem is that how to divide the addresses efficiently and find the best addresses to look for.)
Below is the code where I find nearby users and add them to a list which I pass to my custom widget class.
final List<UserBoxDesign> listOfBoxes = [];
final FirebaseUser currentUser = await auth.currentUser();
final String currentUserId = currentUser.uid;
if (_userLocationSwitchValue == false) { //use default address of the user
currentUserAddress = await _databaseManagement.getUserCollectionValues(
currentUserId, "address");
} else {
//currentUserAddress = //to do, get device location here.
}
if (_searchValue == SearchValues.Users) {
final List<String> userIds = await _databaseManagement.getUserIds();
for (String id in userIds) {
final String otherUserLocations =
await _databaseManagement.getUserCollectionValues(id, "address");
final String distanceMeters = await _findDistanceGoogleMaps(
currentUserAddress, otherUserLocations);
if (distanceMeters == "Address can't be calculated" ||
distanceMeters == "Distance is more than required by user") {
//if it's not possible to calculate the address then just don't do anything with that.
} else {
final double distanceValueInKilometers = (double.parse(
distanceMeters) /
1000)
.roundToDouble();
final String userProfileImageUrl =
await _databaseManagement.getUserCollectionValues(id, "image");
final String username =
await _databaseManagement.getUserCollectionValues(id, "username");
listOfBoxes.add(
UserBoxDesign( //it creates a custom widget for user if user is nearby
userImageUrl: userProfileImageUrl,
distanceFromUser: distanceValueInKilometers,
userId: id,
username: username,
),
); //here we store the latest values inside the reserved data so when we create the page again, the value will be the reservedData value which is not empty anymore
}
print(listOfBoxes);
}
listOfBoxes.sort((itemA,itemB)=>itemA.distanceFromUser.compareTo(itemB.distanceFromUser)); //SORTs the items from closer to more far from user (we can reverse it to far comes first and close goes last)
setState(() {
_isSearchingForUser = false;
});
return listOfBoxes;
Here is the code where I calculate the distance between origin address and destination address.
Future<String> _findDistanceGoogleMaps(
String originAddress, String destinationAddress) async {
final String url =
"https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=$originAddress&destinations=$destinationAddress&key=$GoogleMapsAPIKey";
try {
final response = await http.get(url);
final responseDecoded = json.decode(response.body);
final distanceInMeters = double.parse(responseDecoded["rows"][0]
["elements"][0]["distance"]["value"]
.toString()); //this is the value in meters always so for km , divide by 1000.
if (distanceInMeters < 100000) {
return distanceInMeters.toString();
} else {
return "Distance is more than required by user";
}
} catch (e) {
return "Address can't be calculated";
}
}
this is how my screen looks when I find nearby users.
if you give code example it will be easy to answer.
I can suggest (we had similar task) to use coordinates longitude and latitude and make requests in your range.
So you don't need Distance Matrix API (I think it will be expensive) and your queries will be fast and cheap.
I googled and found out answer here
How to run a geo "nearby" query with firestore?
==after updated question==
You try to use all the logic inside screen and do it synchronously. Because of that you have such a long rendering time.
You calculate everything on user device and pass to a widget return listOfBoxes;
Instead you can try to use Streambuilder, example is here How to efficiently access a firestore reference field's data in flutter?
Organise data in your database in a such way, that you can make request for your purposes: "Find all users within X range sorted by distance AND ...".
In this case Firebase will do it very quickly and pass data to your Streambuilder asynchronously.
I guess that you can keep longitude, latitude and work with them instead of addresses.
Sorry, I cant rewrite your code, not enough info. Just look example by link, there is a good example.
==update 2==
The package https://pub.dev/packages/geoflutterfire
allow to store geo data to Firestore and how to make requests
// Create a geoFirePoint
GeoFirePoint center = geo.point(latitude: 12.960632, longitude: 77.641603);
// get the collection reference or query
var collectionReference = _firestore.collection('locations');
double radius = 50;
String field = 'position';
Stream<List<DocumentSnapshot>> stream = geo.collection(collectionRef: collectionReference)
.within(center: center, radius: radius, field: field);

firebase 3.0 on query

I am building a project where i want to extract a list from a query using firebase 3.0. I am quite new to this but I imagine that there is a simple answer to my question.
I have this structure :
requests : {
luke1 : {
1 : {
.../...
users : {
0 : {
username : joseph,
answered : 0
}
1 : {
username : mark,
answered : 1
}
}
}
}
}
Basically the logged in user (luke1) sends a request to a number of users (joseph and mark) and lets say i'm logged in as user: joseph.
I want to have get a list of requests sent to joseph which where not replied yet
var ref = firebase.database().ref("requests/");
i want to know how can i write the query.
Thanks for taking time to read this and if you need more information from my end, please let me know.
When using Firebase (and in most NoSQL databases), you will often find that you end up modeling the data for the way your app wants to consume it.
So with you current data model, you can easily get the requests sent by a specific user.
ref.child("requests/luke1").on("child_added", ...
But you cannot yet easily find the requests sent to a specific user. To allow querying for that data easily, you could add an inverted data structure to your database:
received: {
joseph: {
0: {
from: luke1
answered: 0
}
}
}
Now you can easily get joseph's unanswered requests with:
ref.child("received/joseph").orderByChild("answered").equalTo(0).on("child_added", ...
Your initial response is likely that this sort of data duplication is bad. But it's actually quite common in NoSQL databases.
There are many more ways to model this structure. For a great introduction to the topic, I recommend this article on NoSQL data modeling.
To achieve this kind of query you need to store in a variable the currentID of your user. After do this, just try something like the next query:
var ref = firebase.database().ref("request").child(currentUserId).child("users");
If I'm not wrong, it will return you the query that you want.

Resources