Связать хранилище Firebase с базой данных Firebase в реальном времени

#android #firebase #kotlin #firebase-realtime-database #backend

#Android #firebase #kotlin #firebase-база данных в реальном времени #серверная часть

Вопрос:

Я создаю образец приложения для инвентаризации Android в Kotlin, используя Google Firebase.
Я использую базу данных firebase в реальном времени для хранения сведений об образце и использую хранилище firebase для хранения изображения образца.

В конце концов я захочу перенести все эти данные в приложение для просмотра.
Мой вопрос: каков наилучший способ связать данные образца в базе данных в реальном времени с соответствующим изображением в хранилище?

мой код

RockEntry.kt

 package com.inven.rock_stock

import android.util.Log
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import java.util.*


class RockEntry {
    var name = ""
    var purchDate = ""
    var local = ""
    var mine = ""
    var weight = ""
    var paid = ""
    var asking = ""
    var description = ""
    var dimensions = ""
    var specimenNumber = ""
    var Uid = ""
    var database = FirebaseDatabase.getInstance()
    var ref = database.getReference("Rocks")

    
constructor(name:String,purchDate:String,local:String,mine:String,
                    weight:String,dimensions:String,paid:String,asking:String,
                    description:String,Uid:String){

        this.name = name
        this.purchDate = purchDate.toString()
        this.local = local
        this.mine = mine
        this.weight = weight
        this.dimensions = dimensions
        this.paid = paid
        this.asking = asking
        this.description = description
        this.Uid = UUID.randomUUID().toString()

    }
 

MainActivity.kt

 package com.inven.rock_stock

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.tasks.Continuation
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ByteArrayOutputStream
import java.io.File
import java.net.URI

var CAMERA_REQUEST_CODE = 0
var database = FirebaseDatabase.getInstance()
var ref = database.getReference("Rocks")
private var mStorageRef: StorageReference? = null


class MainActivity : AppCompatActivity() {
    private val TAG = "MyActivity"
    override fun onCreate(savedInstanceState: Bundle?) {
       mStorageRef = FirebaseStorage.getInstance().getReference("ImagesBB")

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        button.setOnClickListener {
            makeQuery()
        }



        imageBtn.setOnClickListener {
            takePicture()
        }
    }


    private fun makeQuery(){
        var name = name.text.toString()
        var purchDate = purchDate.toString()
        var local = locality.text.toString()
        var mine = mine.text.toString()
        var weight = weight.text.toString()
        var dimensions = dimensions.text.toString()
        var paid = paid.text.toString()
        var asking = asking.text.toString()
        var description = description.text.toString()

        if (!name.isBlank()) {
            ref.child(name.toLowerCase()).setValue(
                RockEntry(
                    name,
                    purchDate,
                    local,
                    mine,
                    weight,
                    paid,
                    asking,
                    dimensions,
                    description
                )
            )
        }

        else {
            Toast.makeText(applicationContext, "Type in a name", Toast.LENGTH_LONG).show()

        }
    }


    private fun takePicture() {
        CAMERA_REQUEST_CODE = 222
        val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        try {
            startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE)
        } catch (e: ActivityNotFoundException) {
            // display error state to the user
        }
    }    

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            CAMERA_REQUEST_CODE -> {
                if (resultCode == Activity.RESULT_OK amp;amp; data != null) {
                    val imageBitmap = data.extras?.get("data") as Bitmap
                    val baos = ByteArrayOutputStream()
                    imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                    val datar = baos.toByteArray()
                    mStorageRef!!.putBytes(datar)
                    }
                }
            }
        }
    }
 

Ответ №1:

«Привязка» файла хранилища FireBase к вашей базе данных в реальном времени может быть выполнена либо

  1. получение местоположения, в котором находится файл в хранилище FireBase, с помощью toString() в ссылке на хранилище
    или
  2. получение URL-адреса, по которому вы можете загрузить файл, с помощью функции .downloadUrl .
    Затем любой из этих параметров может быть сохранен в виде текста в «записи» базы данных в реальном времени.

    пример кода:

       yourStorageBase?.putFile(element)?.addOnSuccessListener   {
        yourStorageBase?.downloadUrl?.addOnSuccessListener { downloadUri ->
                   // #1 
                   var filepath = yourStorageBase.toString()
                   // #2
                   var downloadLink = downloadUri.toString()                                             
        }
      }
     

Примечание:
Если в функции используется следующий код, вы можете «преждевременно» вернуться к вызывающему абоненту до завершения загрузки изображения, что означает, что вы не сможете использовать «ссылки» немедленно. Вы можете написать сопрограмму, чтобы гарантировать, что у ввода-вывода есть время для завершения.

Ответ №2:

Пользователь RecyclerView загружает все данные в ваше приложение, используя класс live model с адаптером данных.

Пользователь DataSnapShot в firebase, чтобы получить все дочерние узлы от родительского.

Ответ №3:

В Firebase DB у вас есть specimen база данных, которая содержит несколько образцов, тогда вам нужно иметь один picture узел в качестве дочернего элемента каждого specimen узла. При загрузке изображения Firebase Storage извлеките его URL-адрес и вставьте его в picture узел под этим конкретным образцом.

Комментарии:

1. Я думаю, что это больше, к чему я направлялся с вопросом, спасибо. У вас есть пример кода для этого? концепция имеет смысл, но я не знаю, как сохранить URL-адрес или запросить его