1

I open the list item, get the data in fetchData(), then I expect that by calling the addTarget() method I will update the current item(name and description). Instead, I create a new one.

Q: How can I update the current one?

enter image description here

class TargetEditFragment : Fragment() {

private var nameEditText: TextInputEditText? = null
private var descriptionEditText: TextInputEditText? = null
private var button: Button? = null
private var databaseReference: DatabaseReference? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.getString(KEY_TARGET_GUID, "")
}

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

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    databaseReference = FirebaseDatabase.getInstance().getReference("targets")
    setupViews()
    fetchData(guid = arguments?.getString(KEY_TARGET_GUID, "") ?: "")
}

private fun setupViews() {
    nameEditText = view?.findViewById(R.id.nameEditText)
    descriptionEditText = view?.findViewById(R.id.descriptionEditText)

    button = view?.findViewById(R.id.addNote)
    button?.setOnClickListener { addTarget() }
}

private fun addTarget() {
    val name = nameEditText?.text.toString().trim()
    val description = descriptionEditText?.text.toString().trim()

    if (!TextUtils.isEmpty(name)) {
        val id: String = databaseReference?.push()?.key.toString()
        val target = Target(guid = id, name = name, description = description)
        databaseReference?.child(id)?.setValue(target)
    } else Log.d("some", "Enter a name")
}

private fun fetchData(guid: String) {
    // Attach a listener to read the data at the target id
    databaseReference?.child(guid)?.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val data = dataSnapshot.value as HashMap<String, String>
            val name = data["name"] ?: ""
            val description = data["description"] ?: ""

            if (name.isEmpty()) Log.d("some", "nameIsEmpty")
            else {
                updateViewsContent(name = name, description = description)
            }
        }

        override fun onCancelled(p0: DatabaseError) {
            Log.d("some", "onCancelled")
        }
    })
}

private fun updateViewsContent(name: String?, description: String?) {
    nameEditText?.text = Editable.Factory.getInstance().newEditable(name)
    descriptionEditText?.text = Editable.Factory.getInstance().newEditable(description)
}

companion object {

    fun newInstance(guid: String): TargetEditFragment =
        TargetEditFragment().apply {
            arguments = Bundle().apply { putString(KEY_TARGET_GUID, guid) }
        }
}
}
Morozov
  • 4,968
  • 6
  • 39
  • 70

1 Answers1

1

There is no way to update an element using the push() method because everytime you call this method a new unique key is generated. In order to perform an update you need to know the key of the element you want to update and use it in your reference. For more informations, please see my answer from the following post:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Not clear( I go into a specific note, `id` I know. If I knowing the `id` why i can t to update the data for this `id`? – Morozov Mar 21 '19 at 13:03
  • 1
    In order to create an update you most likely should use `updateChildren()` method an pass a `Map` as an argument. And your code should look like this: `databaseReference.child("-LaQq-QDnLJHWjR3ru4R").updateChildren(map)` (be sure to have the exact key as in the database). Does it work this way? – Alex Mamo Mar 21 '19 at 13:13
  • I updated the question. The structure is visible in the image. It turns out I will need to do the update in the `fetchData()` or after? – Morozov Mar 21 '19 at 13:21
  • You are still using `push()`. There is **no** way you can update an element using it. Have you tried to use the hardcoded key in the reference? Does it work? – Alex Mamo Mar 21 '19 at 13:24
  • I doesn t understand where in code i need to use it? – Morozov Mar 21 '19 at 13:40
  • Just replace the existing code that you are using to update an element with the solution I provided you. The one using an existing key in a reference, not to generate another key, right? – Alex Mamo Mar 21 '19 at 13:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190442/discussion-between-morozov-and-alex-mamo). – Morozov Mar 21 '19 at 13:50