How to implement a seen feature in Android using firebase database [duplicate] - java

For the past few days i've been trying to show the online/offline status of a user.. For this i have a register activity where they register and their info gets saved in firebase and if they exit an activity i have overriden its onstop method and made the value to set to offline... but if the user suddenly loses internet connection it still shows online.. i cant change it to offline because internet is needed to make a change in the database and the use doesn't have internet... SO how do i set the database value to offline... i googled quite some stuff about this but didnt find anything... Can anyone please help me out please
My code
#Override
protected void onStart() {
super.onStart();
fetchData();
// mDatabaseReference.child("UserData").child(UID).child("Online").setValue("True");
}
#Override
protected void onStop() {
super.onStop();
fetchData();
// mDatabaseReference.child("UserData").child(UID).child("Online").setValue(false);
}

What you're trying to do is known as a presence system. The Firebase Database has a special API to allow this: onDisconnect(). When you attach a handler to onDisconnect(), the write operation you specify will be executed on the server when that server detects that the client has disconnected.
From the documentation on managing presence:
Here is a simple example of writing data upon disconnection by using the onDisconnect primitive:
DatabaseRef presenceRef = FirebaseDatabase.getInstance().getReference("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().setValue("I disconnected!");
In your case this could be as simple as:
protected void onStart() {
super.onStart();
fetchData();
DatabaseReference onlineRef = mDatabaseReference.child("UserData").child(UID).child("Online");
onlineRef.setValue("True");
onlineRef.onDisconnect().setValue("False");
}
Note that this will work in simple cases, but will start to have problems for example when your connection toggles rapidly. In that case it may take the server longer to detect that the client disappears (since this may depends on the socket timing out) than it takes the client to reconnect, resulting in an invalid False.
To handle these situations better, check out the sample presence system in the documentation, which has more elaborate handling of edge cases.

Related

Firebase connection check online offline status in Android

If user turn off both wi-fi, 3g, 4g, and so on and reverse (no internet connection). Firebase database name child connections:(true/false)
So, when internet connections, wi-fi, 3g, 4g, and so on are off or missing, the user is offline so he can't be found.
Remember the two scenarios: Before and After. If user is offline before an other user search him, then he will not displayed in the list result, if user is off-line after an other user search him, then it will display NO MORE AVAILABLE icon on the user
Kindly some one help me for this problem.
To solve this, you can create a new node in your Firebase Realtime Database to hold all online users, so when the user opens the application, you'll immediately add his id to this newly created node. Then, if you want to check if the user is online, just check if his id exists in the list.
You can also add a new property named isOnline for each user in your database and then update it accordingly.
For that, I recommend you using Firebase's built-in onDisconnect() method. It enables you to predefine an operation that will happen as soon as the client becomes disconnected.
See Firebase documentation.
You can also detect the connection state of the user. For many presence-related features, it is useful for your app to know when it is online or offline. Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example also from the official documentation:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
Though this is more than a year late, to clear up the confusion. Alex's question would like to implement a live chat scenario in which each user can view everyone's online status at their ends or on their devices.
A simple solution be to create a node where all users would inject their online status each. e.g.
//say your realtime database has the child `online_statuses`
DatabaseReference online_status_all_users = FirebaseDatabase.getInstance().getReference().child("online_statuses");
//on each user's device when connected they should indicate e.g. `linker` should tell everyone he's snooping around
online_status_all_users.child("#linker").setValue("online");
//also when he's not doing any snooping or if snooping goes bad he should also tell
online_status_all_users.child("#linker").onDisconnect().setValue("offline")
So if another user, say mario checks for linker from his end he can be sure some snooping around is still ongoing if linker is online i.e.
DatabaseReference online_status_all_users = FirebaseDatabase.getInstance().getReference().child("online_statuses");
online_status_all_users.child("#linker").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String snooping_status = dataSnapshot.getValue(String.class);
//mario should decide what to do with linker's snooping status here e.g.
if(snooping_status.contentEquals("online")){
//tell linker to stop doing sh*t
}else{
//tell linker to do a lot of sh****t
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

How can i know if the user is using my android application "now"

I need to know if the user is using my application at the moment.
My idea is to make a method to make his status on in the first activity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_page);
makemeonline();
}
But how can I know if the user didn't just close the application or move it to the background?
You can override the onPause function. In your onPause function, do something like this.
#Override
public void onPause() {
super.onPause();
makeUserIdle();
}
You can not really detect if the user is not connected to internet as I suppose makeMeOnline is calling an API to get the user status posted to some server. If you want the user to track user offline as well, then you might just consider saving the values in your sqlite database and then upload the behaviour data later to the server through another API call when the device is connected to internet.
If you integrate google analytics with your project, you can have an estimate of how many users are currently using your application in the play developer console as well.

How to maintain the presence status of user in firebase Android

I am developing a chat app in which i have to maintain the user online status and the technology i am using is firebase so how can i do that any kind of help is appreciated. Thanks in advance...
Mabz has the right idea conceptually, but I want to highlight a feature of Firebase that specifically addresses your use case.
The trouble that I had run into was updating the RealtimeDatabase with an 'Offline' status. That is, If the client (e.g. your Android app) is offline, how is it supposed to tell the database?
The Solution: Use DatabaseRef.onDisconnect() to set offline status automatically
DatabaseRef presenceRef =
FirebaseDatabase.getInstance().getReference("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().setValue("I disconnected!");
From the documentation:
When you establish an onDisconnect() operation, the operation lives on
the Firebase Realtime Database server. The server checks security to
make sure the user can perform the write event requested, and informs
the your app if it is invalid. The server then monitors the
connection. If at any point the connection times out, or is actively
closed by the Realtime Database client, the server checks security a
second time (to make sure the operation is still valid) and then
invokes the event.
A (slightly) more practical example might do something like this when your app first connects:
DatabaseRef userStatus =
FirebaseDatabase.getInstance().getReference("users/<user_id>/status");
userStatus.onDisconnect.setValue("offline");
userStatus.setValue("online");
NOTE: Please note the order of the last two "online" and "offline" status lines. Do not swap it, or else you might have "ghost users" in case the onDisconnect handler fails to register due to a disconnect itself. (which is actually a race condition problem)
Based upon the information you gave and not considering the performance or bandwidth constraints, here is a way on how I would solve this:
Using a service and a thread in the Real-Time Database:
Within the Real-Time Database, I would have an OnlineStatus thread, and then I would save child Key-Value pairs of User Ids and set to their Value to "Green" or "Yellow" or "Red"; this would give me the status as to whether the user is On-line or Away. So that would look like:
OnlineStatus
User1: Green
User2: Yellow
User3: Red
Create a Service that will check if:
The user is authenticated
The app is in the background
If the user is authenticated and the app is open, then write to the OnlineStatus thread Current User as a key and "Green" as a Value.
If the app is in the background and the user is authenticated, then do the same but "Yellow" is the Value.
Anything else should result in the color "Red". Also note that if the user signs-off, you may want to write "Red" during that operation.
So this allows every device to update Firebase Real-time Database. What remains is adding a reference to your OnlineStatus location to listen to changes through a ValueEventListener.
Hope this helps.
You can use database reference listener “.info/connected” plus disconnect method dbRef.onDisconnect() to solve the presence problem of online user.
Here is some sample code:
onlineStatus = db.getReference("users/"+user.getUid()+"/onlineStatus");
connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
onlineStatus.onDisconnect().setValue("offline");
onlineStatus.setValue("Online");
} else {
onlineStatus.setValue("offline");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
You can read more in this article on my website.

Google Drive Api result.getStatus().isSuccess() always true

I'm managing the callback this way but the result is always success when it shouldn't.
Example:
I search a file that doesn't exist and it doesn't show the log
I search a file when disconnected from the internet and still it doesn't show the log
Even if i create a file on drive when disconnected from the internet and set a callback for its creation, the result is success.
Here is the callback code
ResultCallback<DriveApi.DriveContentsResult> searchCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.e(TAG, "cant open file");
}
}
};
What am i doing wrong?
The Android API has offline support, so performing an operation while offline will not fail. Instead, any changes are queued up to occur when the device comes back online.
Similarly, searching for something that doesn't exist doesn't fail, it just returns an empty result.
You handling of success looks fine, you just aren't testing cases that will actually fail.

Run Android App Twice To Work, Why?

I'm making an android app that test if certain security features on your phone are enabled. For example, if you have password log in enabled or if your data is encrypted on your phone.
For some reason, the app has to be ran twice to test and see if these security features are enabled on the phone or not, and this is the problem I'm trying to solve. I'd like it to test and see if the security features are enabled when the app is created and the first time the app is run, not the second time it is run.
I test if these features are enabled in the onStart() function in my MainActivity file. I included the functions code below:
#Override
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#SuppressLint("NewApi")
public void onStart()
{
super.onStart();
//determine if phone uses lock pattern
//It returns 1 if pattern lock enabled and 0 if pin/password password enabled
ContentResolver cr = getBaseContext().getContentResolver();
lockPatternEnable = Settings.Secure.getInt(cr, Settings.Secure.LOCK_PATTERN_ENABLED, 0);//Settings.System
//returns 1 if pin/password protected. 0 if not
KeyguardManager keyguardManager = (KeyguardManager) getBaseContext().getSystemService(Context.KEYGUARD_SERVICE);
if( keyguardManager.isKeyguardSecure())
{
//it is pin or password protected
pinPasswordEnable=1;
}
else
{
//it is not pin or password protected
pinPasswordEnable=0;
}//http://stackoverflow.com/questions/6588969/device-password-in-android-is-existing-or-not/18716253#18716253
//determine if adb is enabled. works
adb=Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0);
//determine if bluetooth is enabled.works
bluetooth=Settings.Global.getInt(cr, Settings.Global.BLUETOOTH_ON, 0);
//Settings.System BLUETOOTH_DISCOVERABILITY
//determine if wifi is enabled. works
WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled())
{
//wifi is enabled
wifiInt=1;
}
else
wifiInt=0;
//determine if data is encrypted
getDeviceEncryptionencryption();
//determine if gps enabled
}//end of onStart() function
If any more code needs to be posted to answer this question, just let me know, and thanks for your help. Maybe the issue has something to do with the super.onStart();
Does anyone think that a splash loading screen might help solve the issue?
super.onStart(); is fine. Splash screen will not help.
From your code I do not see how you determine how many times it ran.
You also mention testing - is it manual testing or you use any framework? Maybe your framework has some init method which runs before each run and it makes this extra call for onStart().
Issues is not in this code. Use debugger or logcat and figure out who calls you twice and, as #nasch had asked, what happens at first run.
Still, real question to help you remains - what do you mean "call twice". Is it you manually clicking app icon twice or is it some testing framework calls your app twice. Both cases are clear to solve.

Categories

Resources