Java Custom Google Analytics 4 Server-Side Event User-IP - java

In my current Java project, it's easy to track server-side user events in the "old" Google Analytics Universal Project with simple REST calls to Google Analytics. So that location tracking was working, i could override the server ip with the user ip, according to the parameter "&uip=1.2.3.4" (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=de#uip).
As upgrading to GA4 is recommended, I was able to change all the REST parameters in my project and show my events in the new dashboard, except for the user location. I can't find any information about such a parameter. I tried using still "uip" but now all my requests are located to the country of my server.
Unfortunately it's not possible to track the event client side, because my project is a simple REST API, returning only JSON data.
Does anyone have an idea, if there's such a parameter like "uip" for ga4 or if this isn't possible anymore?
In the following way I setup my parameters:
private String getQueryParameters(MeasurementEvent event) {
StringBuilder body = new StringBuilder();
body.append("?v=").append(version);
body.append("&tid=").append(trackingId);
body.append("&cid=").append(event.getClientId());
body.append("&en=").append(eventName);
body.append("&aip=1");
if (StringUtils.hasText(event.getAction())) {
body.append("&ep.useraction=").append(event.getAction());
}
if (StringUtils.hasText(event.getCategory())) {
body.append("&ep.awsregion=").append(event.getCategory());
}
if (StringUtils.hasText(event.getLabel())) {
body.append("&ep.softwarename=").append(event.getLabel());
}
if (StringUtils.hasText(event.getRemoteAddress())) {
body.append("&uip=").append(event.getRemoteAddress());
}
if (StringUtils.hasText(event.getUrl())) {
body.append("&dl=").append(event.getUrl());
}
return body.toString();
}

Related

How to register a listener on a OID / Managed Object using SNMP4J to act on set or get requests the agent receives?

I need to implement a basic snmp agent into my application. This agent should be able to answer get and set requests from snmp browsers on my own OID's. Since most examples for snmp4j are quite old and use the "extend the org.snmp4j.agent.BaseAgent.classapproach" there are of little use.
Therefore tried to understand and strip down the org.snmp4j.agent.example.SampleAgentincluded inside the snmp4j-agent-3.2.1.jar. I managed to get an example working with just the mandatory MIB's ( i at least think they are required because the source of the AgentConfigManager states in a comment they are mandatory snmpv2MIB, snmpMpdMib, targetMIB, communityMIB, notificationMIB, frameworkMIB, usmMIB, vacmMIB, tlsTmMib ) provided by the sample config file.
I than added a custom OID to query to the agend using the following code
MOServer server = new DefaultMOServer();
MOServer[] moServers = new MOServer[]{server};
...
AgentConfigManager agent = new AgentConfigManager(new OctetString(MPv3.createLocalEngineID()),
messageDispatcher,
null,
moServers,
ThreadPool.create("SampleAgent", 3),
configurationFactory,
new DefaultMOPersistenceProvider(moServers, configFile),
new EngineBootsCounterFile(bootCounterFile), null, dhKickstartParameters);
...
agent.initialize();
...
server.register(new MOScalar(new OID("1.someIODshere.0"), MOAccessImpl.ACCESS_READ_ONLY, new OctetString("object 1")), null);
Now i'm missing a way to intercept get or set requests from snmp managers / browsers to return a dynamic value or change the program behavior according to the request.
I kind of expect to be able to bind a kind of event listener to this OID to get notified on requests / changes.
How to watch an OID?
I found it. I was looking at the wrong place. I thought a had to add a listener to the agent, but instead i have to add the listener to the server.
server.addLookupListener(new MOServerLookupListener() {
#Override
public void lookupEvent(MOServerLookupEvent event) {
System.out.println();
((MOScalar)event.getLookupResult()).setValue(new OctetString(new Date().toString()));
}
#Override
public void queryEvent(MOServerLookupEvent event) {
System.out.println();
}
},moScalar);
I can now react to the requests. YAY!

Firebase access Hackernews

So i wanted to check out Firebase and try connecting to Hackernews Firebase database.
I'm using the com.google.firebase:firebase-server-sdk:3.0.3 sdk.
But I am not sure why i am forced to enter a service account.
#Bean
fun firebase(): DatabaseReference {
val options = FirebaseOptions.Builder()
.setDatabaseUrl("https://hacker-news.firebaseio.com/")
.setServiceAccount(this.javaClass.getResourceAsStream("/account.json"))
.build()
val app = FirebaseApp.initializeApp(options)
val instance = FirebaseDatabase.getInstance(app)
return instance.reference
}
Why is setServiceAccount required in this case ? If i leave it out i get following exception:
Caused by: java.lang.IllegalStateException: Service Account must be provided.
at com.google.firebase.internal.Preconditions.checkState(Preconditions.java:173) ~[firebase-server-sdk-3.0.3.jar:na]
at com.google.firebase.FirebaseOptions.<init>(FirebaseOptions.java:129) ~[firebase-server-sdk-3.0.3.jar:na]
Is there a way to connect to Firebase anonymously with a Java client?
This JsFiddle works without a service account:
http://jsfiddle.net/firebase/cm8ne9nh/
If i connect to my own project, this work perfectly nice. I do have a proper service account for my own projects thought...
Thought i might be able to connect with Java the same way.
Any ideas ? Is there a way to connect to Hackernews with the Firebase Java API?
Unfortunately, the Java SDK is only available in two flavors. Java-Client-Android, and Java-Server. Which means, if you want pure client code, you can only really use it on android. This has always been a strange limitation of the available client libraries.
However, what you can do, is wrap the REST API that firebase provides with Java, using HTTP requests to perform everything like you would in any client library.
An example of a repository that has already implemented this is here: https://github.com/j-fischer/rest-on-fire
You could use that one, or you could use your own. But in order to use firebase without a service account, you will have to either use the REST Api or the official Client Libraries which are only writen for Android, iOS, and Web.
Although in the docs here it is not obvious
https://github.com/HackerNews/API
I found this REST API that does not need authentication:
https://hn.algolia.com/api
It can be used in many ways, including with Retrofit & Moshi and no authentication.
Just one example in Kotlin:
interface HackerNewsService {
#GET("search?tags=(story,show_hn,front_page)&hitsPerPage=500")
fun searchStories(#Query("query") q: String, #Query("numericFilters") filters: String, #Query("page") page: Int): Call<SearchResult>
}
val response = hackerNewsService.searchStories(keyword, "created_at_i>$after", 0).execute()
if (response.isSuccessful) {
val searchResult: SearchResult = response.body()!!
println("results! (${searchResult.hits.size}) $searchResult")
} else {
println("uh oh")
}

Sending notifications One to One (Firebase) [duplicate]

I am thinking about keeping all registration ids(push token) in DB and sending notifications to user from iPhone. I tried something like this but did not get any notification.
func sendPNMessage() {
FIRMessaging.messaging().sendMessage(
["body": "hey"],
to: TOKEN_ID,
withMessageID: "1",
timeToLive: 108)
}
What I am doing wrong or maybe it is impossible at all?
Currently it's not possible to send messages from the application itself.
You can send messages from the Firebase Web Console, or from a custom server using the server-side APIs.
What you might want to do is to contact a server (like via http call) and that server will send the message to the user.
This way ensure that the API-KEY of the server is protected.
PS: the sendMessage(..) api is called upstream feature, and can be used to send messages from your app to your server, if you server has an XMPP connection with the FCM server.
Yes you can send push notification through Firebase.Please make sure do NOT include the server-key into your client. There are ways "for not so great people" to find it and do stuff... The Proper way to achieve that is for your client to instruct your app-server to send the notification.
You have to send a HTTP-Post to the Google-API-Endpoint.
You need the following headers:
Content-Type: application/json
Authorization: key={your_server_key}
You can obtain your server key within in the Firebase-Project.
HTTP-Post-Content: Sample
{
"notification": {
"title": "Notification Title",
"text": "The Text of the notification."
},
"project_id": "<your firebase-project-id",
"to":"the specific client-device-id"
}
Google Cloud Functions make it now possible send push notifications from device-to-device without an app server.
From the Google Cloud Functions documentation:
Developers can use Cloud Functions to keep users engaged and up to
date with relevant information about an app. Consider, for example, an
app that allows users to follow one another's activities in the app.
In such an app, a function triggered by Realtime Database writes to
store new followers could create Firebase Cloud Messaging (FCM)
notifications to let the appropriate users know that they have gained
new followers.
Example:
The function triggers on writes to the Realtime Database path where followers are stored.
The function composes a message to send via FCM.
FCM sends the notification message to the user's device.
Here is a demo project for sending device-to-device push notifications with Firebase and Google Cloud Functions.
Diego's answer is very accurate but there's also cloud functions from firebase it's very convenient to send notifications in every change in the db. For example let's say you're building chat application and sending notification in every new follower change.
This function sample is very good example.
For more information about cloud functions you can check official docs.
I have an app that has a "send feedback to developer" section. I also have a User collection in my firestore database. When a user logs into the app, I have that Users data update their FCM token with the following code in my SceneDelegate.swift:
import Firebase
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
authListener = Auth.auth().addStateDidChangeListener({ (auth, user) in
Auth.auth().removeStateDidChangeListener(self.authListener!)
if user != nil {
DispatchQueue.main.async {
let docRef = Firestore.firestore().collection("User").document((user?.email)!)
docRef.getDocument { (snapshot, error) in
guard let snapshot = snapshot else {return}
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
docRef.updateData(["FCMtoken":token])
print("FCM registration token: \(token)")
}
}
}
}
}
})
guard let _ = (scene as? UIWindowScene) else { return }
}
then in my feedback view controller i have this code to send my specific device (but you can look up/fetch which specific device you want in your database where the FCMtoken is stored where i have INSERT-DEVICE-TOKEN-HERE). The url to send to is "https://fcm.googleapis.com/fcm/send" and you can find YOUR-APP-FCM-KEY by going to your project settings in firebase, going to cloud messaging tab and its the server key.
func sendMePushNotification() {
let token = "INSERT-DEVICE-TOKEN-HERE"
if let url = URL(string: "https://fcm.googleapis.com/fcm/send") {
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Content-Type":"application/json", "Authorization":"key=YOUR-APP-FCM-KEY"]
request.httpMethod = "POST"
request.httpBody = "{\"to\":\"\(token)\",\"notification\":{\"title\":\"Feedback Sent!\",\"body\":\"\(self.feedbackBox.text!)\",\"sound\":\"default\",\"badge\":\"1\"},\"data\": {\"customDataKey\": \"customDataValue\"}}".data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, urlresponse, error) in
if error != nil {
print("error")
} else {
print("Successfully sent!.....")
}
}.resume()
}
}
Use onesignal,you can send device to notifications or device to segments ,it can work with firebase in this way
Use onesignal functions to create a specific id,save it in a firebase database ,then when the id can be put in another function that is used to send a notification
Notes: 1-i am using it in my apps with firebase works perfectly
2-i can submit that code,just someone comments so i can find this answer

Spotify Android SDK - how to refresh the Player object after an hour

I am using the Spotify Android SDK version spotifysdk-1.0.0-beta8.aar. I have a valid OAuth token which I am refreshing each hour successfully. This is how I am getting the Spotify Player Object initially
mPlayer = Spotify.getPlayer(playerConfig, this, new Player.InitializationObserver() {
#Override
public void onInitialized(Player player) {
player.addConnectionStateCallback(JukeSpotDashboardActivity.this);
player.addPlayerNotificationCallback(JukeSpotDashboardActivity.this);
player.login(utils.getPreferenceValue(getString(R.string.spotify_access_token)));
}
#Override
public void onError(Throwable throwable) {
Log.e(JukeSpotDashboardActivity.class.getName(),
"Could not initialize player: " + throwable.getMessage());
}
});
At the end of each hour the access token gets refreshed and stored in the shared preferences. How do you guys suggest I use the new access token in the same mPlayer object so that which ever song is being streamed currently won't get stopped and I won't need to recreate this Spotify player object?
I know there is the
mPlayer.login(accessToken);
function, but it did not work when I got the new accessToken and relogged in. Any idea what I am doing wrong?
Once logged in, your application will be able to stream until the application is stopped, the network connection is lost, or the user's premium account has ended. (There may be other events as well.) This means that you don't need to update the Player object with the refreshed access token to continue streaming.
Note that if you're making any other requests using an access token such as adding a track to a playlist, the access token must be updated in whatever tool you're using to perform the request. For example, if you're using kaaes' excellent Spotify Web API client for Android, you'd need to get a new SpotifyService instance based on the refreshed access token.

How do I programatically list my LinkedIn contacts?

I have searched the LinkedIn APIs, but I cannot see a way to get the contacts. I know that there are some applications that have this functionality, but I am wondering is this legal or if they use some kind of partner API?
I think that the Connections API probably does what you need.
This is a Web API, so from Java you would need to use an URL.connect() or Apache HttpClient or something like that, using an appropriately formed request URL. Then you'd need to configure an XML parser to parse the XML response body and extract the contact details.
As the page states, your client needs to be authenticated (as you) to access your contacts, and the API won't let you see details that you cannot see using your web browser.
I created a plugin for Play Framework to easily integrated with LinkedIn's OAuth: http://geeks.aretotally.in/projects/play-framework-linkedin-module.
Hopefully it can help. You should def check out Play, very very cool Java framework.
1) First click below link and add your app to developer account
The r_network scope recently changed to be a LinkedIn partner-only permission. You can apply for access to their partnership program here:
https://developer.linkedin.com/partner-programs/apply
2) After successfully creation of your app on developer account make permission of r_network
3) Insert Following code after importing all required linked-in sdk file from this https://developer.linkedin.com/docs/android-sdk
private static final String topCardUrl = "https://api.linkedin.com/v1/people/~:(id,first-name,email-address,last-name,num-connections,headline,picture-url,industry,summary,specialties,positions:(id,title,summary,start-date,end-date,is-current,company:(id,name,type,size,industry,ticker)),educations:(id,school-name,field-of-study,start-date,end-date,degree,activities,notes),associations,interests,num-recommenders,date-of-birth,publications:(id,title,publisher:(name),authors:(id,name),date,url,summary),patents:(id,title,summary,number,status:(id,name),office:(name),inventors:(id,name),date,url),languages:(id,language:(name),proficiency:(level,name)),skills:(id,skill:(name)),certifications:(id,name,authority:(name),number,start-date,end-date),courses:(id,name,number),recommendations-received:(id,recommendation-type,recommendation-text,recommender),honors-awards,three-current-positions,three-past-positions,volunteer)?format=json";
public void getUserData() {
APIHelper apiHelper = APIHelper.getInstance(MainActivity.this);
apiHelper.getRequest(MainActivity.this, topCardUrl, new ApiListener() {
#Override
public void onApiSuccess(ApiResponse result) {
try {
//here you get data in json format
//you have to parse it and bind with adapter for connection list
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onApiError(LIApiError error) {
}
});
}

Categories

Resources