-1

At the moment I managed to add a date field to my model Target. The structure you can see in the screen:

enter image description here

Also i have a fragment where I display the calendar. How can I tell by clicking on a date if there is a target created for that date?

class CalendarFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_calendar, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupViews()
    }

    private fun setupViews() {
        calendarView.setOnDateChangeListener { view, year, month, dayOfMonth ->
            dateView.text = //name of Target
        }
    }
}

For example now i display only date in calendar with next code:

dateView.text = "Selected date is " + dayOfMonth + "/" + (month + 1) + "/" + year

enter image description here

Q: How i can display target name for a specific date?

UPD: Right now i insert this code in my fragment, which i took from this answer:

val uid = FirebaseAuth.getInstance().currentUser!!.uid
        val rootRef = FirebaseDatabase.getInstance().reference
        val targetsRef = rootRef.child("targets").child("users").child(uid).child("targets")
        val query = targetsRef.orderByChild("date")
        val valueEventListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                for (ds in dataSnapshot.children) {
                    val name = ds.child("name").getValue(String::class.java)
                    Log.d("some", name)
                }
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.d("some", databaseError.getMessage()) //Don't ignore errors!
            }
        }
        query.addListenerForSingleValueEvent(valueEventListener)

But now when I go into the fragment I get the names of all the targets created regardless of the selected date in the calendar.

Morozov
  • 4,968
  • 6
  • 39
  • 70
  • Do you have a single target within your `Targets` node or even more? – Alex Mamo Sep 19 '19 at 12:22
  • @AlexMamo there can be as many as you want – Morozov Sep 19 '19 at 12:24
  • In that case, which one of them do you want to be displayed? – Alex Mamo Sep 19 '19 at 12:25
  • @AlexMamo the task is to display goal for each date. for example: for October 24, the name `target` for September 9, the name of the `op` Also check please now screen – Morozov Sep 19 '19 at 12:27
  • @AlexMamo I clearly described the issue or is it still worth it to try to describe better? or perhaps it is a more complex task? – Morozov Sep 19 '19 at 12:41
  • 1
    I think I understood you but I'm not sure how to formulate an answer. – Alex Mamo Sep 19 '19 at 12:43
  • The last question, you want to get all objects within `targets`, get the value of `date` property and add it to calendar, right? – Alex Mamo Sep 19 '19 at 12:51
  • @AlexMamo I don't quite understand your question) let us on order. I have a target with a date field (for example October 24) when I click on the date in the calendar (October 24), I see the goals that have the date field September 24. Smth like this maybe https://miro.medium.com/max/720/0*Xe3ia_3xCQs6ItpJ.png – Morozov Sep 19 '19 at 13:02
  • *when I click on the date in the calendar (October 24)* Do you already have that date in the calendar? If yes, on the click on that date, you want get all targets that have set the date to `October 24` and change it to `September 24`? Is this waht you need? – Alex Mamo Sep 19 '19 at 13:06
  • *Do you already have that date in the calendar* no, but i can detect the date: `"Selected date is " + dayOfMonth + "/" + (month + 1) + "/" + year` And no, i didn.t want to change date of target(this is i did). I want to display target name on date(24 october) – Morozov Sep 19 '19 at 13:47
  • So the only thing that you need is when clicking on a date in the calendar, you need to query using that date to find one or more targets. Is this what you need? – Alex Mamo Sep 19 '19 at 13:51
  • @AlexMamo yep, right!) – Morozov Sep 19 '19 at 13:52
  • Ok, I'll write you an answer right away. – Alex Mamo Sep 19 '19 at 13:52
  • Please check my answer below and tell me if it works. – Alex Mamo Sep 19 '19 at 14:12
  • @AlexMamo yes, ofc – Morozov Sep 19 '19 at 14:25

1 Answers1

1

According to the earlier comments, you confirmed that you want when someone is clicking on a date in the calendar to query the targets node using that date to find one or more results. But first thing first.

For searching purposes, storing the date as a String might work, since you can use for comparation whereEqualTo() method but if you want to order the results, it won't work since the strings are order lexicographically. So you might consider storing the date as a ServerValue.TIMESTAMP, as explained in my answer from the following post:

Furthermore, I will provide you the solution for your particular use, where the date is a String but can simply change it later if you'll consider using the solution above. So I will use as a selected date the following String:

val selectedDate = "24 October 2019"

Assuming that this value is coming from the selection of the date from your calendar, please try the code below:

val uid = FirebaseAuth.getInstance().currentUser!!.uid
val rootRef = FirebaseDatabase.getInstance().reference
val targetsRef = rootRef.child("targets").child("users").child(uid).child("targets")
val query = targetsRef.orderByChild("date").equalTo(selectedDate)
val valueEventListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (ds in dataSnapshot.children) {
            val name = ds.child("name").getValue(String::class.java)
            Log.d(TAG, name)
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
    }
}
query.addListenerForSingleValueEvent(valueEventListener)

In this case, the result in your logcat will be:

target

Edit:

I get the names of all the targets created regardless of the selected date in the calendar.

You get all the dates because you forgot to call .equalTo(selectedDate). So please change:

val query = targetsRef.orderByChild("date")

to

val query = targetsRef.orderByChild("date").equalTo(selectedDate)
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • I start from first problem: https://stackoverflow.com/questions/58018104/save-date-in-firebase-realtime-database Can u check please? – Morozov Sep 20 '19 at 08:35
  • Ok, I'll take a look and if I'll know the answer, I'll write it to you. Regarding my answer above, does it work? – Alex Mamo Sep 20 '19 at 09:27
  • I cannot check the answer above as I have not yet matured the date in the correct format so again the same question which I to you threw and try to understand – Morozov Sep 20 '19 at 09:30
  • Sasi Kanth's comment is correct, you should convert that literal String that you get from the calendar to a Date object using `SimpleDateFormatter` and than convert to long so you can query, right? – Alex Mamo Sep 20 '19 at 09:34
  • sorry for a silly question, but from where the variable selectedDate, how to initialize it correctly? – Morozov Sep 21 '19 at 19:31
  • The `selectedDate` is the date that you get from the calendar. Remember, the date that you should have converted from String to long, right? – Alex Mamo Sep 22 '19 at 09:12
  • still the problem is that I don't know how to get this date for the date I click on in the calendar. I need use smth like getDate? – Morozov Sep 24 '19 at 16:01
  • also `selectedDate` must be String/Double/Boolean in `equalTo()` – Morozov Sep 24 '19 at 16:20
  • @Morozov No, `selectedDate` must be a number that is equal to the long number that exist in your database. So when you get the date from your calendar simply convert it to the type you have in you database. Only then the query will work. – Alex Mamo Sep 24 '19 at 21:11
  • "selectedDate must be a number" - what type of variable? I can't use `Long` type – Morozov Sep 25 '19 at 18:49
  • @Morozov Sure you can use `long`. Why do you say you can't? – Alex Mamo Sep 29 '19 at 10:46