kalfalarin_omer
kalfalarin_omer

Reputation: 85

cant get downloadUrl after upload the image to FireBase in Flutter

after i upload my image to Firebase i cant get it's download url. i wanna get it to show uploaded pics in other pages. here is my codes:

  
import 'dart:io';
import 'package:firebase/GetPic.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

class ImageUploadPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return ImageUploadPageState();
  }

}

class ImageUploadPageState extends State{
  TextEditingController _control= TextEditingController();
 
  File _selectedImage;
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("IMAGE UPLOAD PAGE"),
        actions: [
          IconButton(
              icon: Icon(Icons.arrow_right_alt), onPressed: (){
                Navigator.push(context, MaterialPageRoute(
                  builder: (context)=>GetPic(),));
          }),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
                child: Text("Galeriden resim seçin"),
                onPressed: (){_selectImage();}),
            Expanded(
                child: _selectedImage== null ? 
Text("there is no pic"): Image.file(_selectedImage)),
            Form(
              key: _formKey,
              child: Padding(
                padding: const EdgeInsets.all(25.0),
                child: TextFormField(
                controller: _control,
                  decoration: InputDecoration(
                    labelText: "image's name",
                    labelStyle: TextStyle(color: Colors.greenAccent)
                  ),
                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 17),
                ),
              ),
            ),
            RaisedButton(
                child: Text("Upload image"),
                onPressed: (){_uploadImage();}),
          ]
        ),
      ),
    );
  }

  void _selectImage() async {
    var _iamge= await ImagePicker.pickImage(source: ImageSource.gallery);
    _selelctedImage= _image;
    setState(() {});
  }

  Future<String> _uploadImage() async {
    _formKey.currentState.save();
    String imageFileName = _control.text;
    

    final Reference ref = await FirebaseStorage.instance.ref().child("deneme").child("resimler").child(imageFileName);

    UploadTask uploadTask = ref.putFile(_selectedImage);
    var downloadUrl = await (await uploadTask.snapshot).ref.getDownloadURL();
    debugPrint(downloadUrl.toString());

    return downloadUrl.toString();
  }

}

i have TextFormField that gives image's name. if i upload an image(same or different) with same name i can get last one's donwload url normally. in my opinion image's name that i uploaded cant be seen at first try unlike to second try. so i am fail to get download url at first try and success at second try. i hope i could tell my problem clearly. i will be so glad if somebody helps.

Here is my android/build.gradle

    buildscript {
    ext.kotlin_version = '1.3.50'
    repositories {
        google()  // Google's Maven repository
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.4'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'

    }
}
allprojects {
    repositories {
        google()  // Google's Maven repository
        jcenter()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Here is my app/build.gradle

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.firebase.crashlytics'

android {
    compileSdkVersion 29

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "meb.firebase"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.20"
    testImplementation 'junit:junit:4.13.1'
    androidTestImplementation 'androidx.test:runner:1.3.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation platform('com.google.firebase:firebase-bom:26.1.0')
    implementation 'com.android.support:multidex:1.0.3'
    implementation "com.google.firebase:firebase-messaging:20.2.4"
}

and al last Here is my error message:

E/flutter (17095): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: [firebase_storage/object-not-found] No object exists at the desired reference.
E/flutter (17095): #0      MethodChannelReference.getDownloadURL (package:firebase_storage_platform_interface/src/method_channel/method_channel_reference.dart:57:7)
E/flutter (17095): <asynchronous suspension>
E/flutter (17095): #1      Reference.getDownloadURL (package:firebase_storage/src/reference.dart:94:48)
E/flutter (17095): #2      ImageUploadPageState._resimYukle (package:firebase/ImageUploadPage.dart:83:61)
E/flutter (17095): <asynchronous suspension>
E/flutter (17095): #3      ImageUploadPageState.build.<anonymous closure> (package:firebase/ImageUploadPage.dart:62:31)
E/flutter (17095): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
E/flutter (17095): #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1111:38)
E/flutter (17095): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183:24)
E/flutter (17095): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598:11)
E/flutter (17095): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:287:5)
E/flutter (17095): #9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:222:7)
E/flutter (17095): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:476:9)
E/flutter (17095): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:77:12)
E/flutter (17095): #12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122:9)
E/flutter (17095): #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
E/flutter (17095): #14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18)
E/flutter (17095): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7)
E/flutter (17095): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:358:19)
E/flutter (17095): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:338:22)
E/flutter (17095): #18     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:267:11)
E/flutter (17095): #19     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:295:7)
E/flutter (17095): #20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:240:7)
E/flutter (17095): #21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:213:7)
E/flutter (17095): #22     _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter (17095): #23     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (17095): #24     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (17095): #25     _invoke1 (dart:ui/hooks.dart:265:10)
E/flutter (17095): #26     _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)
E/flutter (17095): 

Upvotes: 1

Views: 184

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317467

Just await the result of putFile to wait until the upload is complete before requesting the URL.

    await ref.putFile(_selectedImage);
    var downloadUrl = await ref.getDownloadURL();
    debugPrint(downloadUrl);

I suggest reviewing the documentation for more details.

Upvotes: 2

Related Questions