androidflutterdartgoogle-play-consoleflutter-hive

How to publish an App, which uses Hive to store data?


I launched the App moneyreminder on the Play Store. The problem is the part which uses Hive to store data doesn't work. When I run it in release mode I get an error. I use Android Studio and Language Flutter. I launched the App with the google Play console.

This is the error that I get

adb: failed to install C:\Users\Niklas\StudioProjects\moneyreminder\build\app\outputs\flutter-apk\app.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.muellerniklas.moneyreminder signatures do not match previously installed version; ignoring!]

This is my link to the App.

This is my main folder

import 'package:flutter/material.dart';
import 'package:debt/colors.dart';
import 'package:debt/add.dart';
import 'package:debt/data.dart';
import 'package:flutter/foundation.dart';


import 'package:hive_flutter/hive_flutter.dart';
late Box box;

List<Data>datalist=[];
Future <void> main() async{
  WidgetsFlutterBinding.ensureInitialized();

  await Hive.initFlutter();

  Hive.registerAdapter(DataAdapter());
  box = await Hive.openBox("infos");
  //wandelt die daten für die Anzeige um
  Map<dynamic, dynamic> data2 = box.toMap();

  //macht aus map liste
  data2.forEach((key, value) {
    if(kDebugMode){
      Data w =Data (key, value);
      datalist.add(w);
    }


  });

runApp(const MaterialApp(
  home: debt(),
  debugShowCheckedModeBanner: false,

));}
// ignore: camel_case_types
class debt extends StatefulWidget {
  const debt({Key? key}) : super(key: key);


  @override
  _debtState createState() => _debtState();
}

// ignore: camel_case_types
class _debtState extends State<debt> {

  Map<String, dynamic> values = {};
  String text = 'Text';
  double w = 100;
  double h = 20;
  Widget quoteTemplate(data){
    return ValueListenableBuilder<Box>(
        valueListenable: Hive.box('infos').listenable(),
        builder: (context, box, widget) {
          return
      Card(
        

      margin: const EdgeInsets.fromLTRB(16, 16, 16, 0),
      child:Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
          crossAxisAlignment: CrossAxisAlignment.center,    // y Achse
          children: <Widget>[
      Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
        crossAxisAlignment: CrossAxisAlignment.center,// y Achse

        children: <Widget>[
          Container(alignment: Alignment.center,
            width: 100,
            height: h,
            child: Text(
              data.people,
              style: TextStyle(
                fontSize:  18,
                color: Colors.grey[600],
              )

            ),
          ),
          const SizedBox(height: 6,),
          Container(
            alignment: Alignment.center,

            child: Text(
                data.money,
                style: TextStyle(
                  fontSize:  14,
                  color: Colors.grey[800],
                )

            ),
          ),
        ],
      )
            ,Container(//delete
              alignment: Alignment.center,

              child: TextButton(style: TextButton.styleFrom(

              ),
                onPressed: (){
        box.delete(data.people);
        setState(() {
          Map<dynamic, dynamic> data2 = box.toMap();
          datalist=[];
          data2.forEach((key, value) {
              if(kDebugMode){
                Data w =Data (key, value);
                datalist.add(w);
              }
          });
        });
                },
                child: const Icon(Icons.delete,color: lightblue,),
              ),
            ),
            Container(//minusbutton
              alignment: Alignment.center,

              child: TextButton(style: TextButton.styleFrom(//Minus Butten

              ),
                onPressed: (){
                  var zwischenspeicher = box.get(data.people);

                  double zwischenspeicher2= double.parse(zwischenspeicher) - 1.0;
                  var schulden = zwischenspeicher2.toString();



                  box.put(data.people,schulden);
                  //Updatet das widget
                  setState(() {
                    Map<dynamic, dynamic> data2 = box.toMap();
                    datalist=[];
                    data2.forEach((key, value) {
                      if(kDebugMode){
                        Data w =Data (key, value);
                        datalist.add(w);
                      }
                    });
                  });
                },
                child: const Icon(Icons.remove,color: darkblue,),
              ),
            ),
            Container(//plus Button
              alignment: Alignment.center,

              child: TextButton(style: TextButton.styleFrom(

              ),
                onPressed: (){
                  var zwischenspeicher = box.get(data.people);

                  var zwischenspeicher2= double.parse(zwischenspeicher) + 1;
                  var schulden = zwischenspeicher2.toString();



          box.put(data.people,schulden);

                  setState(() {
                    Map<dynamic, dynamic> data2 = box.toMap();
                    datalist=[];
                    data2.forEach((key, value) {
                      if(kDebugMode){
                        Data w =Data (key, value);
                        datalist.add(w);
                      }
                    });
                  });
                },
                child: const Icon(Icons.add,color: darkbrown,),
              ),
            ),
          ],
      ),
    );});
  }Widget buttond(){
    return
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Expanded(child: Align(
        alignment: FractionalOffset.bottomRight,
        child:

        FloatingActionButton(
        onPressed: () {
          _awaitReturnValueFromSecondScreen(context);
        },
        child: const Icon(Icons.add),backgroundColor: lightbrown,


    ),),),
      );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: lightblue ,
        title: const Text("Money Reminder"),
        centerTitle: true,
      ),
      body:

      Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView(
          children: [
        Column(
          children: datalist.map((data)=> quoteTemplate(data)).toList(),
    ),

          ],
        ),
      ),bottomNavigationBar: Padding(
      padding: const EdgeInsets.fromLTRB(20,0,20,10),
      child:


        ElevatedButton(
          onPressed: () {
            _awaitReturnValueFromSecondScreen(context);
          },
          //child: const Icon(Icons.add,color: Colors.white,),

          child: const Text('add/edit debt',style: TextStyle(fontSize: 18,fontFamily: "Futura",color: Colors.white),),
    style: ElevatedButton.styleFrom( backgroundColor:lightbrown,)


        )

    ),



    );
  }


void _awaitReturnValueFromSecondScreen(BuildContext context) async {

  // start the SecondScreen and wait for it to finish with a result
  final result = await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => const add(),
      ));

  // after the SecondScreen result comes back update the Text widget with it
  setState(() {
    datalist = result;
  });
  }
}

This is the second screen where I use Hive

import 'package:flutter/material.dart';
import 'package:debt/colors.dart';
import 'package:debt/data.dart';
import 'package:flutter/foundation.dart';

import 'package:debt/main.dart';
// ignore: camel_case_types
class add extends StatefulWidget {
  const add({Key? key}) : super(key: key);
  @override
  State<add> createState() => _addState();
}
// ignore: camel_case_types
class _addState extends State<add> {
   String text = "Text2";
   Map<String, dynamic> data = {};

   double size = 40;
   double space = 9;
   List<Data>datalist=[];
   TextEditingController name = TextEditingController();
   TextEditingController debt = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(title: const Text("add debt"), centerTitle: true,backgroundColor: lightblue,),
      body: Card(

          margin: EdgeInsets.fromLTRB(size, size, size, 300),
          child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SizedBox(width: 1,height: space,),
                TextField(
                  controller: name,
                  style: const TextStyle(color: Colors.black54),
                  decoration: const InputDecoration(
                    hintText: "Niklas, Peter",
                    labelText: "Person",

                    hintStyle: TextStyle(fontFamily: "Futura",),
                    labelStyle: TextStyle(fontSize: 24, fontFamily: "Futura"),
                    border: UnderlineInputBorder(),
                    fillColor: white,
                    filled: true,
                  ),
                  keyboardType: TextInputType.name,
                  obscureText: false,
                  
                  maxLines: 1,
                ),
                SizedBox(width: 1,height: space,),
                TextField(
                  controller: debt,
                  style: const TextStyle(color: Colors.black54),
                  decoration: const InputDecoration(
                    hintText: "10€",
                    labelText: "Debt",
                    hintStyle: TextStyle(fontFamily: "Futura",),
                    labelStyle: TextStyle(fontSize: 24, fontFamily: "Futura"),
                    border: UnderlineInputBorder(),
                    fillColor: white,
                    filled: true,
                  ),
                  keyboardType: TextInputType.number,
                  obscureText: false,
                  maxLength: 16,
                  maxLines: 1,
                ),
                const SizedBox(width: 1,height: 70,),

                ElevatedButton(onPressed: ()  async{
                  var _name = name.text;
                  var _debt = debt.text;
                  var _debt_ = "";
                  var split = ", ";
                  //damit auch "," und nicht nur ", " als Trennung gilt
                  if (_name.contains(",")){
                    split =",";
                  }

                  var listevonnamen = _name.split(split);

                  // Wandelt Komma in . um um keine Missverständnisse zu erzeugen

                  //für doppelte Texteingabe mit Komma

                  for(var i = 0;i<listevonnamen.length;i++){
                  //texteingaben Komma zu .
                    _name = listevonnamen[i];
                    if(_debt.contains(",")){
                      for(var f = 0; f<_debt.length; f++){
                        //geht durch jeden Buchstaben und überprüft ob ein Komma vorhanden ist
                        if (_debt[f]== ","){
                          _debt_ = _debt_ + ".";
                        }
                        else{
                          _debt_ = _debt_ + _debt[f];
                        }
                      }

                      _debt = _debt_ ;

                    }
                  //var valuecheck = data.containsKey("$_name");
                  var schulden = "";
                  var zwischenspeicher = "";
                  double zwischenspeicher2 = 0;
                  bool checker = box.containsKey(_name);
                  //überprüft ob konto schon vorhanden
                  if (checker == false){
                    
                    data.addAll({_name: _debt});
                    schulden = _debt;
                  }

                  else  { // wiederholung

                    zwischenspeicher = box.get(_name);
                    //addiert alte daten zu neuen

                    zwischenspeicher2= double.parse(zwischenspeicher) + double.parse(_debt) ;
                    schulden = zwischenspeicher2.toString();
                  }

                  // daten werden gespeichert
                  box.put(_name,schulden);}
                  Map<dynamic, dynamic> data2 = box.toMap();

                    //macht aus map liste
                  data2.forEach((key, value) {
                    if(kDebugMode){
                      Data w =Data (key, value);
                      datalist.add(w);
                    }

                  });
                  _sendDataBack(context);

                },
                  child: const Text("Send"),

                  style: ElevatedButton.styleFrom(
                      minimumSize: const Size(400,70),
                      textStyle: const TextStyle(fontSize: 24,),
                      backgroundColor: lightbrown,
                      foregroundColor: Colors.white,
                      alignment: Alignment.center

                  ),
                ),
              ]

          )
      )
    );
  }

//daten zurücksenden
void _sendDataBack(BuildContext context) {
  List textToSendBack = datalist;



  Navigator.pop(context, textToSendBack,);
}
}

My Project has more files for hive and the class named data.


Solution

  • It is impossible. There is not any special requirements for Hive used apps to stores. I am pretty sure that you are doing something programmatically wrong, but you are thinking that is because you published wrongly.

    SOLUTION: RUN APP WITH flutter run -— release. And check whether everything is working as intended.