Why deleteData of google fit history api not working? - android

This code delete history in today:
val cal = Calendar.getInstance()
cal.time = Date()
val endTime = cal.timeInMillis
cal.add(Calendar.DAY_OF_YEAR, -1)
val startTime = cal.timeInMillis
val request = DataDeleteRequest.Builder()
.setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
// .addDataType(DataType.TYPE_STEP_COUNT_DELTA)
.deleteAllData ()
.deleteAllSessions ()
.build()
Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.deleteData(request)
.addOnSuccessListener {
Log.i(TAG, "Successfully deleted today's sessions") }
.addOnFailureListener {
// The deletion will fail if the requesting app tries to delete data
// that it did not insert.
Log.i(TAG, "Failed to delete today's sessions")
}
Result : logcat show message successfully:
03-02 18:12:54.949 15978-15978/vnit.com.testrealm I/StepCounter: Successfully deleted today's sessions
But i use function read data, it still exist:
private fun readData() {
Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.readDailyTotal(DataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener { dataSet ->
val total = (if (dataSet.isEmpty)
0
else
dataSet.dataPoints[0].getValue(Field.FIELD_STEPS).asInt()).toLong()
Log.i(TAG, "Total steps: " + total)
txtStep.setText(total.toString())
}
.addOnFailureListener(
object : OnFailureListener {
override fun onFailure(e: Exception) {
Log.w(TAG, "There was a problem getting the step count.", e)
}
})
}
I am trying to open Google fit app, it still display's old value.
Why can't delete old history?
Thanks all.

Related

I want weekly Sleep data from google fit

I am not getting weekly data from google fit (Yes, There is data in google fit which I have track using watch), but Yes I am getting today's date data.
I am attaching code snippet.
Start date = "2022-09-13T00:00:00Z"
End date = "2022-09-20T23:59:59Z"
private fun readSleepSessions(startTime : Long , endTime : Long) {
val client = Fitness.getSessionsClient(requireContext(), getGoogleAccount())
val sessionReadRequest = SessionReadRequest.Builder()
.read(DataType.TYPE_SLEEP_SEGMENT)
.includeSleepSessions()
.readSessionsFromAllApps()
.enableServerQueries()
.setTimeInterval(1663027200000, 1663718399000, TimeUnit.MILLISECONDS)
.build()
client.readSession(sessionReadRequest)
.addOnSuccessListener {
Log.d(TAG, "readSleepSessions: $sessionReadRequest")
dumpSleepSessions(it)
}
.addOnFailureListener {
Log.e("MainScreen", "Unable to read sleep sessions", it)
}
}
private fun dumpSleepSessions(response: SessionReadResponse) {
if (response.sessions.isNotEmpty()){
for (session in response.sessions) {
dumpSleepSession(session, response.getDataSet(session))
Log.d(TAG, "dumpSleepSessions: ${response.sessions}")
}
}else{
Log.d(TAG, "dumpSleepSessionsResponse: ${response.status}")
}
}
private fun dumpSleepSession(session: Session, dataSets: List<DataSet>) {
dumpSleepSessionMetadata(session)
dumpSleepDataSets(dataSets)
}
private fun dumpSleepDataSets(dataSets: List<DataSet>) {
for (dataSet in dataSets) {
for (dataPoint in dataSet.dataPoints) {
val sleepStageOrdinal = dataPoint.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
val sleepStage = sleepTargetName[sleepStageOrdinal]
val durationMillis =
dataPoint.getEndTime(TimeUnit.MILLISECONDS) - dataPoint.getStartTime(TimeUnit.MILLISECONDS)
val duration = TimeUnit.MILLISECONDS.toMinutes(durationMillis)
Log.d(TAG, "\t$sleepStage: $duration (minutes)")
}
}

Android app, putBytes to Firebase not working

Im (doing tutorial on YT) trying to put my image to firebase,
As far as I can see, I can't connect to the database, but I don't know where the problem is and what I am doing wrong
but when I try I have something like this in logcat:
2021-11-01 06:57:40.660 32702-32702/pl.edu.pb.mymemory E/CreateActivity: Exception with Firebase storage
com.google.firebase.storage.StorageException: The operation retry limit has been exceeded.
at com.google.firebase.storage.UploadTask.snapStateImpl(UploadTask.java:524)
at com.google.firebase.storage.UploadTask.snapStateImpl(UploadTask.java:50)
at com.google.firebase.storage.StorageTask.snapState(StorageTask.java:343)
at com.google.firebase.storage.StorageTask.getFinalResult(StorageTask.java:453)
at com.google.firebase.storage.StorageTask.getResult(StorageTask.java:273)
at com.google.firebase.storage.StorageTask.getResult(StorageTask.java:41)
There is my function:
private fun saveDataToFirebase() {
val customGameName = etGameName.text.toString()
Log.i(TAG, "Save data to Firebase")
var didEncounteredError = false
val uploadedImageUrls = mutableListOf<String>()
for ((index,photoUri) in chosenImageUris.withIndex()) {
//downgrading the quality of the image
val imageByteArray = getImageByteArray(photoUri)
val filePath = "images/$customGameName/${System.currentTimeMillis()}-${index}.jpg"
val photoReference = storage.reference.child(filePath)
Log.i(TAG, "Trying to upload: ${photoReference}")
//wait until it succeeds or fails
photoReference.putBytes(imageByteArray)
.continueWithTask { photoUploadTask ->
Log.i(TAG, "Uploaded bytes: ${photoUploadTask.result?.bytesTransferred}")
photoReference.downloadUrl
}.addOnCompleteListener { downloadUrlTask ->
if (!downloadUrlTask.isSuccessful) {
Log.e(TAG, "Exception with Firebase storage", downloadUrlTask.exception)
Toast.makeText(this, "Failed to upload image", Toast.LENGTH_SHORT).show()
didEncounteredError = true
return#addOnCompleteListener
}
if(didEncounteredError){
return#addOnCompleteListener
}
val downloadUrl = downloadUrlTask.result.toString()
uploadedImageUrls.add(downloadUrl)
Log.i(TAG, "Finished uploading $photoUri, num uploaded ${uploadedImageUrls.size}")
if(uploadedImageUrls.size == chosenImageUris.size) {
handleAllImagesUploaded(customGameName, uploadedImageUrls)
}
}
}
}
My repository on git
In my case it was wrong date on phone.
Fixing date resolved an issue

Need help solving Firebase query in Android Studio

I'm trying to see if this "employee" has a service where the serviceComplete field is false (in other words trying to see if this employee has an active service that is not complete) if a Toast message pops up letting the employee know he cannot accept more services has he has an active one. If not the employee should be able to accept the service.
My problem is no matter what I do this firebase query seems to think there are documents in my DB that do not exist. Every time I go to accept the service it displays the toast. Meaning there is a collection "services" where a document has the field "serviceCompleted" which is equal to "false" but in my DB there is no collection "services" under employees
My database showing no collection "services" exist underneath "employees"
and here is my Kotlin code
fun setButton(serviceID: String, eID: String){
val btnAcceptService = view.findViewById<Button>(R.id.btnAcceptService)
btnAcceptService.setOnClickListener {
val queryEmpServices = database.collection("employees").document(eID).collection("services").whereEqualTo("serviceComplete", false)
queryEmpServices.get().addOnSuccessListener { documents ->
if (documents != null){
Toast.makeText(applicationContext,"You already have a service active!", Toast.LENGTH_SHORT).show()
}else {
database.collection("services").document(serviceID).update("saccept", true).addOnSuccessListener {
database.collection("services").document(serviceID).get().addOnSuccessListener { document ->
if (document != null) {
val Location = document.get("ulocation").toString()
val serviceType = document.get("serviceType").toString()
val uComment = document.get("ucomment").toString()
val uID = document.get("uid").toString()
if (document.getBoolean("saccept") == true) {
database.collection("users").document(document.get("uid").toString()).collection("services").document(serviceID).update("saccept", true).addOnSuccessListener {
database.collection("employees").document(mAuth.currentUser!!.uid).get().addOnSuccessListener { document ->
if (document != null) {
val calendar = Calendar.getInstance()
val simpleDateFormat = SimpleDateFormat("dd-MM-yyyy HH:mm:ss")
val acceptDate = simpleDateFormat.format(calendar.time)
val eFullName = document.get("ename").toString() + " " + document.get("esurname").toString()
val eCompany = document.get("ecompany").toString()
database.collection("users").document(uID).get().addOnSuccessListener { document ->
val uName = document.get("name").toString()
val uPhonenumber = document.get("phonenumber").toString()
val serviceAccept = EmployeeServiceAccept(acceptDate, serviceID, Location, serviceType, uComment, uName, uPhonenumber, false)
database.collection("employees").document(mAuth.currentUser!!.uid).collection("acceptedservices").document(serviceID).set(serviceAccept)
database.collection("services").document(serviceID).update("acceptedby", eFullName + ", " + eCompany)
database.collection("users").document(uID).collection("services").document(serviceID).update("acceptedby", eFullName + ", " + eCompany)
Toast.makeText(applicationContext, "Service Accepted", Toast.LENGTH_SHORT).show()
}
}
}
}
}
} else {
Toast.makeText(applicationContext, "Failed to accept service", Toast.LENGTH_SHORT).show()
}
When you are using the Task.addOnSuccessListener(OnSuccessListener) method on a Query object, the result that you get can be a success or a failure, never both and never null. It will always be one, or the other.
That being said, you should never check the documents object against nullity because it can never be null. What you should do instead, is to check the "documents" object, which is of type QuerySnapshot to see if isEmpty() or not:
if (!documents.isEmpty){
Toast.makeText(applicationContext,"You already have a service active!", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(applicationContext,"You don't have a service active!", Toast.LENGTH_SHORT).show()
}
Where indeed the Toast message from the "else" part of the statement will be displayed, as there are no documents present in the QuerySnapshot object:
"You don't have a service active!"

Asynchronous operations not performing as expected- Kotlin Android

I have written a code to fetch data from Cloud Firestore and am trying to implement the network calls using coroutines. I have tried to follow the official guides as much as possible, but since the functions have been left incomplete in those docs, I have made adjustments according to my requirements, but those might be the problem itself.
Here's the function which fetches the data:
suspend fun fetchHubList(): MutableLiveData<ArrayList<HubModel>> = withContext(Dispatchers.IO) {
val hubList = ArrayList<HubModel>()
val liveHubData = MutableLiveData<ArrayList<HubModel>>()
hubsListCollection.get().addOnSuccessListener { collection ->
if (collection != null) {
Log.d(TAG, "Data fetch successful!")
for (document in collection) {
Log.d(TAG, "the document id is ")
hubList.add(document.toObject(HubModel::class.java))
}
} else {
Log.d(TAG, "No such document")
}
}.addOnFailureListener { exception ->
Log.d(TAG, "get failed with ", exception)
}
if (hubList.isEmpty()) {
Log.d(TAG, "Collection size 0")
} else {
Log.d(TAG, "Collection size not 0")
}
liveHubData.postValue(hubList)
return#withContext liveHubData
}
And here is the ViewModel class which is calling this method:
class HubListViewModel(application: Application): AndroidViewModel(application) {
// The data which will be observed
var hubList = MutableLiveData<ArrayList<HubModel>>()
private val hubListDao = HubListDao()
init {
viewModelScope.launch (Dispatchers.IO){
hubList = hubListDao.fetchHubList()
Log.d(TAG, "Array List fetched")
}
}
}
Using the tag messages I know that an empty list is being returned, which I know from another question of mine, is because the returned ArrayList is not in sync with the fetching operation, but I don't know why, since I've wrapped the whole function inside a with context block. Please tell me why the return and fetching is not being performed sequentially.
you should add this dependency "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.4.3". It allows you to use await() to replace callbacks.
suspend fun fetchHubList(): List<HubModel>? = try {
hubsListCollection.get().await().map { document ->
Log.d(TAG, "the document id is ${document.id}")
document.toObject(HubModel::class.java)
}.apply {
Log.d(TAG, "Data fetch successful!")
Log.d(TAG, "Collection size is $size")
}
} catch (e: Exception) {
Log.d(TAG, "get failed with ", e)
null
}
Dispatchers.IO is not necessary since firebase APIs are main-safe
class HubListViewModel(application: Application): AndroidViewModel(application) {
val hubList = MutableLiveData<List<HubModel>>()
private val hubListDao = HubListDao()
init {
viewModelScope.launch {
hubList.value = hubListDao.fetchHubList()
Log.d(TAG, "List fetched")
}
}
}

Google fit empty dataset

I'm developing a step counter with Google Fit.
I tried to implement as it is defined in Google Fit docs. But the problem is that when I query step count it always returns empty dataset but when I query with readDailyTotal function it returns a dataset.
I am not able to find what is the cause.
I get the required permission for required step count permission
val fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE, FitnessOptions.ACCESS_READ)
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.build()
if (! GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(activity),
fitnessOptions)) {
GoogleSignIn.requestPermissions(
activity, // your activity
REQUEST_CODE_GOOGLE_FIT_PERMISSIONS,
GoogleSignIn.getLastSignedInAccount(activity),
fitnessOptions
)
} else {
onSuccess.invoke()
}
I subscribe to the application for recording step counts.
Fitness.getRecordingClient(context, client!!)
.subscribe(DataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener {
onSuccess.invoke()
}
.addOnFailureListener { e ->
onFail.invoke(e)
}
I query 1 week period with history API but it always returns an empty dataset.
// Setting a start and end date using a range of 1 week before this moment.
val cal = Calendar.getInstance()
val now = Date()
cal.time = now
val endTime = cal.timeInMillis
cal.add(Calendar.WEEK_OF_YEAR, -1)
val startTime = cal.timeInMillis
val dateFormat = DateFormat.getDateInstance()
Log.i(TAG, "Range Start: " + dateFormat.format(startTime))
Log.i(TAG, "Range End: " + dateFormat.format(endTime))
val readRequest = DataReadRequest.Builder()
// The data request can specify multiple data types to return, effectively
// combining multiple data queries into one call.
// In this example, it's very unlikely that the request is for several hundred
// datapoints each consisting of a few steps and a timestamp. The more likely
// scenario is wanting to see how many steps were walked per day, for 7 days.
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
// Analogous to a "Group By" in SQL, defines how data should be aggregated.
// bucketByTime allows for a time span, whereas bucketBySession would allow
// bucketing by "sessions", which would need to be defined in code.
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.enableServerQueries()
.build()
Fitness.getHistoryClient(context, client)
.readData(readRequest)
.addOnSuccessListener { dataReadResponse ->
dumpDataSets(dataReadResponse.dataSets)
onSuccess.invoke(dataReadResponse)
}
.addOnFailureListener { e ->
onFail.invoke(e)
}
.addOnCompleteListener { task ->
dumpDataSets(task.result!!.dataSets)
onComplete.invoke(task)
}
Datasets can be found in buckets:
dataReadResponse.buckets.forEach { bucket ->
bucket.dataSet.forEach { dataSet ->
dataSet.dataPoints.forEach { dataPoint ->
// USE DataPoint
}
}
}

Categories

Resources